diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/bullet/area_bullet.cpp | 24 | ||||
-rw-r--r-- | modules/bullet/area_bullet.h | 4 | ||||
-rw-r--r-- | modules/bullet/collision_object_bullet.cpp | 2 | ||||
-rw-r--r-- | modules/bullet/space_bullet.cpp | 7 | ||||
-rw-r--r-- | modules/enet/networked_multiplayer_enet.cpp | 148 | ||||
-rw-r--r-- | modules/enet/networked_multiplayer_enet.h | 5 | ||||
-rw-r--r-- | modules/gdnative/doc_classes/GDNativeLibrary.xml | 8 | ||||
-rw-r--r-- | modules/gdscript/gdscript_editor.cpp | 16 | ||||
-rw-r--r-- | modules/gdscript/gdscript_highlighter.cpp | 18 | ||||
-rw-r--r-- | modules/gridmap/grid_map_editor_plugin.cpp | 12 | ||||
-rw-r--r-- | modules/mono/editor/mono_bottom_panel.cpp | 9 | ||||
-rw-r--r-- | modules/websocket/emws_peer.cpp | 6 | ||||
-rw-r--r-- | modules/websocket/emws_server.cpp | 13 | ||||
-rw-r--r-- | modules/websocket/emws_server.h | 3 | ||||
-rw-r--r-- | modules/websocket/lws_peer.cpp | 39 | ||||
-rw-r--r-- | modules/websocket/lws_server.cpp | 18 | ||||
-rw-r--r-- | modules/websocket/lws_server.h | 3 | ||||
-rw-r--r-- | modules/websocket/websocket_peer.cpp | 2 | ||||
-rw-r--r-- | modules/websocket/websocket_server.cpp | 3 | ||||
-rw-r--r-- | modules/websocket/websocket_server.h | 4 |
20 files changed, 241 insertions, 103 deletions
diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp index ec78cddb6a..bfb452d109 100644 --- a/modules/bullet/area_bullet.cpp +++ b/modules/bullet/area_bullet.cpp @@ -68,8 +68,9 @@ AreaBullet::AreaBullet() : } AreaBullet::~AreaBullet() { - // Call "remove_all_overlapping_instantly();" is not necessary because the exit - // signal are handled by godot, so just clear the array + // signal are handled by godot, so just clear without notify + for (int i = overlappingObjects.size() - 1; 0 <= i; --i) + overlappingObjects[i].object->on_exit_area(this); } void AreaBullet::dispatch_callbacks() { @@ -122,24 +123,21 @@ void AreaBullet::scratch() { isScratched = true; } -void AreaBullet::remove_all_overlapping_instantly() { - CollisionObjectBullet *supportObject; +void AreaBullet::clear_overlaps(bool p_notify) { for (int i = overlappingObjects.size() - 1; 0 <= i; --i) { - supportObject = overlappingObjects[i].object; - call_event(supportObject, PhysicsServer::AREA_BODY_REMOVED); - supportObject->on_exit_area(this); + if (p_notify) + call_event(overlappingObjects[i].object, PhysicsServer::AREA_BODY_REMOVED); + overlappingObjects[i].object->on_exit_area(this); } overlappingObjects.clear(); } -void AreaBullet::remove_overlapping_instantly(CollisionObjectBullet *p_object, bool p_notify) { - CollisionObjectBullet *supportObject; +void AreaBullet::remove_overlap(CollisionObjectBullet *p_object, bool p_notify) { for (int i = overlappingObjects.size() - 1; 0 <= i; --i) { - supportObject = overlappingObjects[i].object; - if (supportObject == p_object) { + if (overlappingObjects[i].object == p_object) { if (p_notify) - call_event(supportObject, PhysicsServer::AREA_BODY_REMOVED); - supportObject->on_exit_area(this); + call_event(overlappingObjects[i].object, PhysicsServer::AREA_BODY_REMOVED); + overlappingObjects[i].object->on_exit_area(this); overlappingObjects.remove(i); break; } diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h index 4104780de9..b2046c684e 100644 --- a/modules/bullet/area_bullet.h +++ b/modules/bullet/area_bullet.h @@ -150,9 +150,9 @@ public: void set_on_state_change(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant()); void scratch(); - void remove_all_overlapping_instantly(); + void clear_overlaps(bool p_notify); // Dispatch the callbacks and removes from overlapping list - void remove_overlapping_instantly(CollisionObjectBullet *p_object, bool p_notify); + void remove_overlap(CollisionObjectBullet *p_object, bool p_notify); virtual void on_collision_filters_change(); virtual void on_collision_checker_start() {} diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index 77f8df34cb..05c0e653df 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -70,7 +70,7 @@ CollisionObjectBullet::CollisionObjectBullet(Type p_type) : CollisionObjectBullet::~CollisionObjectBullet() { // Remove all overlapping, notify is not required since godot take care of it for (int i = areasOverlapped.size() - 1; 0 <= i; --i) { - areasOverlapped[i]->remove_overlapping_instantly(this, /*Notify*/ false); + areasOverlapped[i]->remove_overlap(this, /*Notify*/ false); } destroyBulletCollisionObject(); diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 51a76ff8c5..8450a66f65 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -996,7 +996,7 @@ public: } void reset() { - result_collision_objects.empty(); + result_collision_objects.clear(); } }; @@ -1031,7 +1031,10 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran for (int i = recover_broad_result.result_collision_objects.size() - 1; 0 <= i; --i) { btCollisionObject *otherObject = recover_broad_result.result_collision_objects[i]; - if (!p_body->get_bt_collision_object()->checkCollideWith(otherObject) || !otherObject->checkCollideWith(p_body->get_bt_collision_object()) || (p_infinite_inertia && !otherObject->isStaticOrKinematicObject())) + if (p_infinite_inertia && !otherObject->isStaticOrKinematicObject()) { + otherObject->activate(); // Force activation of hitten rigid, soft body + continue; + } else if (!p_body->get_bt_collision_object()->checkCollideWith(otherObject) || !otherObject->checkCollideWith(p_body->get_bt_collision_object())) continue; if (otherObject->getCollisionShape()->isCompound()) { diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp index f3f4acd768..28b19224fb 100644 --- a/modules/enet/networked_multiplayer_enet.cpp +++ b/modules/enet/networked_multiplayer_enet.cpp @@ -115,9 +115,6 @@ Error NetworkedMultiplayerENet::create_client(const IP_Address &p_ip, int p_port #endif address.port = p_port; - //enet_address_set_host (& address, "localhost"); - //address.port = p_port; - unique_id = _gen_unique_id(); /* Initiate the connection, allocating the enough channels */ @@ -128,7 +125,7 @@ Error NetworkedMultiplayerENet::create_client(const IP_Address &p_ip, int p_port ERR_FAIL_COND_V(!peer, ERR_CANT_CREATE); } - //technically safe to ignore the peer or anything else. + // Technically safe to ignore the peer or anything else. connection_status = CONNECTION_CONNECTING; active = true; @@ -148,13 +145,13 @@ void NetworkedMultiplayerENet::poll() { /* Wait up to 1000 milliseconds for an event. */ while (true) { - if (!host || !active) //might have been disconnected while emitting a notification + if (!host || !active) // Might have been disconnected while emitting a notification return; int ret = enet_host_service(host, &event, 1); if (ret < 0) { - //error, do something? + // Error, do something? break; } else if (ret == 0) { break; @@ -172,7 +169,7 @@ void NetworkedMultiplayerENet::poll() { int *new_id = memnew(int); *new_id = event.data; - if (*new_id == 0) { //data zero is sent by server (enet won't let you configure this). Server is always 1 + if (*new_id == 0) { // Data zero is sent by server (enet won't let you configure this). Server is always 1 *new_id = 1; } @@ -180,22 +177,22 @@ void NetworkedMultiplayerENet::poll() { peer_map[*new_id] = event.peer; - connection_status = CONNECTION_CONNECTED; //if connecting, this means it connected t something! + connection_status = CONNECTION_CONNECTED; // If connecting, this means it connected to something! emit_signal("peer_connected", *new_id); if (server) { - //someone connected, let it know of all the peers available + // Someone connected, notify all the peers available for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) { if (E->key() == *new_id) continue; - //send existing peers to new peer + // Send existing peers to new peer ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE); encode_uint32(SYSMSG_ADD_PEER, &packet->data[0]); encode_uint32(E->key(), &packet->data[4]); enet_peer_send(event.peer, SYSCH_CONFIG, packet); - //send the new peer to existing peers + // Send the new peer to existing peers packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE); encode_uint32(SYSMSG_ADD_PEER, &packet->data[0]); encode_uint32(*new_id, &packet->data[4]); @@ -220,12 +217,12 @@ void NetworkedMultiplayerENet::poll() { } else { if (server) { - //someone disconnected, let it know to everyone else + // Someone disconnected, notify everyone else for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) { if (E->key() == *id) continue; - //send the new peer to existing peers + ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE); encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]); encode_uint32(*id, &packet->data[4]); @@ -246,7 +243,7 @@ void NetworkedMultiplayerENet::poll() { case ENET_EVENT_TYPE_RECEIVE: { if (event.channelID == SYSCH_CONFIG) { - //some config message + // Some config message ERR_CONTINUE(event.packet->dataLength < 8); // Only server can send config messages @@ -292,13 +289,13 @@ void NetworkedMultiplayerENet::poll() { packet.from = *id; if (target == 0) { - //re-send the everyone but sender :| + // Re-send to everyone but sender :| incoming_packets.push_back(packet); - //and make copies for sending + // And make copies for sending for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) { - if (uint32_t(E->key()) == source) //do not resend to self + if (uint32_t(E->key()) == source) // Do not resend to self continue; ENetPacket *packet2 = enet_packet_create(packet.packet->data, packet.packet->dataLength, flags); @@ -307,12 +304,12 @@ void NetworkedMultiplayerENet::poll() { } } else if (target < 0) { - //to all but one + // To all but one - //and make copies for sending + // And make copies for sending for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) { - if (uint32_t(E->key()) == source || E->key() == -target) //do not resend to self, also do not send to excluded + if (uint32_t(E->key()) == source || E->key() == -target) // Do not resend to self, also do not send to excluded continue; ENetPacket *packet2 = enet_packet_create(packet.packet->data, packet.packet->dataLength, flags); @@ -321,18 +318,18 @@ void NetworkedMultiplayerENet::poll() { } if (-target != 1) { - //server is not excluded + // Server is not excluded incoming_packets.push_back(packet); } else { - //server is excluded, erase packet + // Server is excluded, erase packet enet_packet_destroy(packet.packet); } } else if (target == 1) { - //to myself and only myself + // To myself and only myself incoming_packets.push_back(packet); } else { - //to someone else, specifically + // To someone else, specifically ERR_CONTINUE(!peer_map.has(target)); enet_peer_send(peer_map[target], event.channelID, packet.packet); } @@ -341,14 +338,14 @@ void NetworkedMultiplayerENet::poll() { incoming_packets.push_back(packet); } - //destroy packet later.. + // Destroy packet later.. } else { ERR_CONTINUE(true); } } break; case ENET_EVENT_TYPE_NONE: { - //do nothing + // Do nothing } break; } } @@ -377,16 +374,46 @@ void NetworkedMultiplayerENet::close_connection() { if (peers_disconnected) { enet_host_flush(host); - OS::get_singleton()->delay_usec(100); //wait 100ms for disconnection packets to send + OS::get_singleton()->delay_usec(100); // Wait 100ms for disconnection packets to send } enet_host_destroy(host); active = false; incoming_packets.clear(); - unique_id = 1; //server is 1 + unique_id = 1; // Server is 1 connection_status = CONNECTION_DISCONNECTED; } +void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) { + + ERR_FAIL_COND(!active); + ERR_FAIL_COND(!is_server()); + ERR_FAIL_COND(!peer_map.has(p_peer)) + + if (now) { + enet_peer_disconnect_now(peer_map[p_peer], 0); + + // enet_peer_disconnect_now doesn't generate ENET_EVENT_TYPE_DISCONNECT, + // notify everyone else, send disconnect signal & remove from peer_map like in poll() + + for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) { + + if (E->key() == p_peer) + continue; + + ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE); + encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]); + encode_uint32(p_peer, &packet->data[4]); + enet_peer_send(E->get(), SYSCH_CONFIG, packet); + } + + emit_signal("peer_disconnected", p_peer); + peer_map.erase(p_peer); + } else { + enet_peer_disconnect_later(peer_map[p_peer], 0); + } +} + int NetworkedMultiplayerENet::get_available_packet_count() const { return incoming_packets.size(); @@ -440,9 +467,9 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer } ENetPacket *packet = enet_packet_create(NULL, p_buffer_size + 12, packet_flags); - encode_uint32(unique_id, &packet->data[0]); //source ID - encode_uint32(target_peer, &packet->data[4]); //dest ID - encode_uint32(packet_flags, &packet->data[8]); //dest ID + encode_uint32(unique_id, &packet->data[0]); // Source ID + encode_uint32(target_peer, &packet->data[4]); // Dest ID + encode_uint32(packet_flags, &packet->data[8]); // Dest ID copymem(&packet->data[12], p_buffer, p_buffer_size); if (server) { @@ -450,14 +477,14 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer if (target_peer == 0) { enet_host_broadcast(host, channel, packet); } else if (target_peer < 0) { - //send to all but one - //and make copies for sending + // Send to all but one + // and make copies for sending int exclude = -target_peer; for (Map<int, ENetPeer *>::Element *F = peer_map.front(); F; F = F->next()) { - if (F->key() == exclude) // exclude packet + if (F->key() == exclude) // Exclude packet continue; ENetPacket *packet2 = enet_packet_create(packet->data, packet->dataLength, packet_flags); @@ -465,14 +492,14 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer enet_peer_send(F->get(), channel, packet2); } - enet_packet_destroy(packet); //original packet no longer needed + enet_packet_destroy(packet); // Original packet no longer needed } else { enet_peer_send(E->get(), channel, packet); } } else { ERR_FAIL_COND_V(!peer_map.has(1), ERR_BUG); - enet_peer_send(peer_map[1], channel, packet); //send to server for broadcast.. + enet_peer_send(peer_map[1], channel, packet); // Send to server for broadcast.. } enet_host_flush(host); @@ -482,7 +509,7 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer int NetworkedMultiplayerENet::get_max_packet_size() const { - return 1 << 24; //anything is good + return 1 << 24; // Anything is good } void NetworkedMultiplayerENet::_pop_current_packet() { @@ -511,16 +538,12 @@ uint32_t NetworkedMultiplayerENet::_gen_unique_id() const { (uint32_t)OS::get_singleton()->get_unix_time(), hash); hash = hash_djb2_one_32( (uint32_t)OS::get_singleton()->get_user_data_dir().hash64(), hash); - /* hash = hash_djb2_one_32( - (uint32_t)OS::get_singleton()->get_unique_id().hash64(), hash ); - */ + (uint32_t)((uint64_t)this), hash); // Rely on ASLR heap hash = hash_djb2_one_32( - (uint32_t)((uint64_t)this), hash); //rely on aslr heap - hash = hash_djb2_one_32( - (uint32_t)((uint64_t)&hash), hash); //rely on aslr stack + (uint32_t)((uint64_t)&hash), hash); // Rely on ASLR stack - hash = hash & 0x7FFFFFFF; // make it compatible with unsigned, since negatie id is used for exclusion + hash = hash & 0x7FFFFFFF; // Make it compatible with unsigned, since negative ID is used for exclusion } return hash; @@ -596,7 +619,7 @@ size_t NetworkedMultiplayerENet::enet_compress(void *context, const ENetBuffer * return 0; if (ret > int(outLimit)) - return 0; //do not bother + return 0; // Do not bother copymem(outData, enet->dst_compressor_mem.ptr(), ret); @@ -651,7 +674,35 @@ void NetworkedMultiplayerENet::_setup_compressor() { void NetworkedMultiplayerENet::enet_compressor_destroy(void *context) { - //do none + // Nothing to do +} + +IP_Address NetworkedMultiplayerENet::get_peer_address(int p_peer_id) const { + + ERR_FAIL_COND_V(!peer_map.has(p_peer_id), IP_Address()); + ERR_FAIL_COND_V(!is_server() && p_peer_id != 1, IP_Address()); + ERR_FAIL_COND_V(peer_map[p_peer_id] == NULL, IP_Address()); + + IP_Address out; +#ifdef GODOT_ENET + out.set_ipv6((uint8_t *)&(peer_map[p_peer_id]->address.host)); +#else + out.set_ipv4((uint8_t *)&(peer_map[p_peer_id]->address.host)); +#endif + + return out; +} + +int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const { + + ERR_FAIL_COND_V(!peer_map.has(p_peer_id), 0); + ERR_FAIL_COND_V(!is_server() && p_peer_id != 1, 0); + ERR_FAIL_COND_V(peer_map[p_peer_id] == NULL, 0); +#ifdef GODOT_ENET + return peer_map[p_peer_id]->address.port; +#else + return peer_map[p_peer_id]->address.port; +#endif } void NetworkedMultiplayerENet::_bind_methods() { @@ -659,9 +710,12 @@ void NetworkedMultiplayerENet::_bind_methods() { ClassDB::bind_method(D_METHOD("create_server", "port", "max_clients", "in_bandwidth", "out_bandwidth"), &NetworkedMultiplayerENet::create_server, DEFVAL(32), DEFVAL(0), DEFVAL(0)); ClassDB::bind_method(D_METHOD("create_client", "ip", "port", "in_bandwidth", "out_bandwidth"), &NetworkedMultiplayerENet::create_client, DEFVAL(0), DEFVAL(0)); ClassDB::bind_method(D_METHOD("close_connection"), &NetworkedMultiplayerENet::close_connection); + ClassDB::bind_method(D_METHOD("disconnect_peer", "id", "now"), &NetworkedMultiplayerENet::disconnect_peer, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_compression_mode", "mode"), &NetworkedMultiplayerENet::set_compression_mode); ClassDB::bind_method(D_METHOD("get_compression_mode"), &NetworkedMultiplayerENet::get_compression_mode); ClassDB::bind_method(D_METHOD("set_bind_ip", "ip"), &NetworkedMultiplayerENet::set_bind_ip); + ClassDB::bind_method(D_METHOD("get_peer_address"), &NetworkedMultiplayerENet::get_peer_address); + ClassDB::bind_method(D_METHOD("get_peer_port"), &NetworkedMultiplayerENet::get_peer_port); ADD_PROPERTY(PropertyInfo(Variant::INT, "compression_mode", PROPERTY_HINT_ENUM, "None,Range Coder,FastLZ,ZLib,ZStd"), "set_compression_mode", "get_compression_mode"); @@ -696,7 +750,7 @@ NetworkedMultiplayerENet::~NetworkedMultiplayerENet() { close_connection(); } -// sets IP for ENet to bind when using create_server +// Sets IP for ENet to bind when using create_server // if no IP is set, then ENet bind to ENET_HOST_ANY void NetworkedMultiplayerENet::set_bind_ip(const IP_Address &p_ip) { ERR_FAIL_COND(!p_ip.is_valid() && !p_ip.is_wildcard()); diff --git a/modules/enet/networked_multiplayer_enet.h b/modules/enet/networked_multiplayer_enet.h index 440e9b5400..0e8dd67160 100644 --- a/modules/enet/networked_multiplayer_enet.h +++ b/modules/enet/networked_multiplayer_enet.h @@ -115,11 +115,16 @@ public: virtual int get_packet_peer() const; + virtual IP_Address get_peer_address(int p_peer_id) const; + virtual int get_peer_port(int p_peer_id) const; + Error create_server(int p_port, int p_max_clients = 32, int p_in_bandwidth = 0, int p_out_bandwidth = 0); Error create_client(const IP_Address &p_ip, int p_port, int p_in_bandwidth = 0, int p_out_bandwidth = 0); void close_connection(); + void disconnect_peer(int p_peer, bool now = false); + virtual void poll(); virtual bool is_server() const; diff --git a/modules/gdnative/doc_classes/GDNativeLibrary.xml b/modules/gdnative/doc_classes/GDNativeLibrary.xml index 308d8defc3..754a6d2514 100644 --- a/modules/gdnative/doc_classes/GDNativeLibrary.xml +++ b/modules/gdnative/doc_classes/GDNativeLibrary.xml @@ -9,12 +9,6 @@ <demos> </demos> <methods> - <method name="get_config_file"> - <return type="ConfigFile"> - </return> - <description> - </description> - </method> <method name="get_current_dependencies" qualifiers="const"> <return type="PoolStringArray"> </return> @@ -29,6 +23,8 @@ </method> </methods> <members> + <member name="config_file" type="ConfigFile" setter="set_config_file" getter="get_config_file"> + </member> <member name="load_once" type="bool" setter="set_load_once" getter="should_load_once"> </member> <member name="reloadable" type="bool" setter="set_reloadable" getter="is_reloadable"> diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 87d8fe1bf5..0d52f0a995 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -1333,13 +1333,23 @@ static void _find_identifiers_in_block(GDScriptCompletionContext &context, int p for (int i = 0; i < context.block->statements.size(); i++) { - if (context.block->statements[i]->line > p_line) + GDScriptParser::Node *statement = context.block->statements[i]; + if (statement->line > p_line) continue; - if (context.block->statements[i]->type == GDScriptParser::BlockNode::TYPE_LOCAL_VAR) { + GDScriptParser::BlockNode::Type statementType = statement->type; + if (statementType == GDScriptParser::BlockNode::TYPE_LOCAL_VAR) { - const GDScriptParser::LocalVarNode *lv = static_cast<const GDScriptParser::LocalVarNode *>(context.block->statements[i]); + const GDScriptParser::LocalVarNode *lv = static_cast<const GDScriptParser::LocalVarNode *>(statement); result.insert(lv->name.operator String()); + } else if (statementType == GDScriptParser::BlockNode::TYPE_CONTROL_FLOW) { + + const GDScriptParser::ControlFlowNode *cf = static_cast<const GDScriptParser::ControlFlowNode *>(statement); + if (cf->cf_type == GDScriptParser::ControlFlowNode::CF_FOR) { + + const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(cf->arguments[0]); + result.insert(id->name.operator String()); + } } } } diff --git a/modules/gdscript/gdscript_highlighter.cpp b/modules/gdscript/gdscript_highlighter.cpp index 5b8b652c29..4e89851bf2 100644 --- a/modules/gdscript/gdscript_highlighter.cpp +++ b/modules/gdscript/gdscript_highlighter.cpp @@ -71,24 +71,8 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_ Color keyword_color; Color color; - int in_region = -1; + int in_region = text_editor->_is_line_in_region(p_line); int deregion = 0; - for (int i = 0; i < p_line; i++) { - int ending_color_region = text_editor->_get_line_ending_color_region(i); - if (in_region == -1) { - in_region = ending_color_region; - } else if (in_region == ending_color_region) { - in_region = -1; - } else { - const Map<int, TextEdit::Text::ColorRegionInfo> &cri_map = text_editor->_get_line_color_region_info(i); - for (const Map<int, TextEdit::Text::ColorRegionInfo>::Element *E = cri_map.front(); E; E = E->next()) { - const TextEdit::Text::ColorRegionInfo &cri = E->get(); - if (cri.region == in_region) { - in_region = -1; - } - } - } - } const Map<int, TextEdit::Text::ColorRegionInfo> cri_map = text_editor->_get_line_color_region_info(p_line); const String &str = text_editor->get_line(p_line); diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 869492232c..f523eef895 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -1046,14 +1046,14 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { options->get_popup()->add_item(TTR("Previous Floor"), MENU_OPTION_PREV_LEVEL, KEY_Q); options->get_popup()->add_item(TTR("Next Floor"), MENU_OPTION_NEXT_LEVEL, KEY_E); options->get_popup()->add_separator(); - options->get_popup()->add_check_item(TTR("Clip Disabled"), MENU_OPTION_CLIP_DISABLED); + options->get_popup()->add_radio_check_item(TTR("Clip Disabled"), MENU_OPTION_CLIP_DISABLED); options->get_popup()->set_item_checked(options->get_popup()->get_item_index(MENU_OPTION_CLIP_DISABLED), true); - options->get_popup()->add_check_item(TTR("Clip Above"), MENU_OPTION_CLIP_ABOVE); - options->get_popup()->add_check_item(TTR("Clip Below"), MENU_OPTION_CLIP_BELOW); + options->get_popup()->add_radio_check_item(TTR("Clip Above"), MENU_OPTION_CLIP_ABOVE); + options->get_popup()->add_radio_check_item(TTR("Clip Below"), MENU_OPTION_CLIP_BELOW); options->get_popup()->add_separator(); - options->get_popup()->add_check_item(TTR("Edit X Axis"), MENU_OPTION_X_AXIS, KEY_Z); - options->get_popup()->add_check_item(TTR("Edit Y Axis"), MENU_OPTION_Y_AXIS, KEY_X); - options->get_popup()->add_check_item(TTR("Edit Z Axis"), MENU_OPTION_Z_AXIS, KEY_C); + options->get_popup()->add_radio_check_item(TTR("Edit X Axis"), MENU_OPTION_X_AXIS, KEY_Z); + options->get_popup()->add_radio_check_item(TTR("Edit Y Axis"), MENU_OPTION_Y_AXIS, KEY_X); + options->get_popup()->add_radio_check_item(TTR("Edit Z Axis"), MENU_OPTION_Z_AXIS, KEY_C); options->get_popup()->set_item_checked(options->get_popup()->get_item_index(MENU_OPTION_Y_AXIS), true); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Cursor Rotate X"), MENU_OPTION_CURSOR_ROTATE_X, KEY_A); diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp index f1cf0bcdf5..1b5a303835 100644 --- a/modules/mono/editor/mono_bottom_panel.cpp +++ b/modules/mono/editor/mono_bottom_panel.cpp @@ -407,9 +407,14 @@ void MonoBuildTab::stop_build() { void MonoBuildTab::_issue_activated(int p_idx) { - ERR_FAIL_INDEX(p_idx, issues.size()); + ERR_FAIL_INDEX(p_idx, issues_list->get_item_count()); - const BuildIssue &issue = issues[p_idx]; + // Get correct issue idx from issue list + int issue_idx = this->issues_list->get_item_metadata(p_idx); + + ERR_FAIL_INDEX(issue_idx, issues.size()); + + const BuildIssue &issue = issues[issue_idx]; if (issue.project_file.empty() && issue.file.empty()) return; diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp index d3330d683c..e0b987b4d7 100644 --- a/modules/websocket/emws_peer.cpp +++ b/modules/websocket/emws_peer.cpp @@ -148,12 +148,14 @@ void EMWSPeer::close() { IP_Address EMWSPeer::get_connected_host() const { - return IP_Address(); + ERR_EXPLAIN("Not supported in HTML5 export"); + ERR_FAIL_V(IP_Address()); }; uint16_t EMWSPeer::get_connected_port() const { - return 1025; + ERR_EXPLAIN("Not supported in HTML5 export"); + ERR_FAIL_V(0); }; EMWSPeer::EMWSPeer() { diff --git a/modules/websocket/emws_server.cpp b/modules/websocket/emws_server.cpp index c9ddae0c8c..3eb93e4152 100644 --- a/modules/websocket/emws_server.cpp +++ b/modules/websocket/emws_server.cpp @@ -58,6 +58,19 @@ PoolVector<String> EMWSServer::get_protocols() const { return out; } +IP_Address EMWSServer::get_peer_address(int p_peer_id) const { + + return IP_Address(); +} + +int EMWSServer::get_peer_port(int p_peer_id) const { + + return 0; +} + +void EMWSServer::disconnect_peer(int p_peer_id) { +} + EMWSServer::EMWSServer() { } diff --git a/modules/websocket/emws_server.h b/modules/websocket/emws_server.h index aa089ea40d..9ec4ce72c8 100644 --- a/modules/websocket/emws_server.h +++ b/modules/websocket/emws_server.h @@ -46,6 +46,9 @@ public: bool is_listening() const; bool has_peer(int p_id) const; Ref<WebSocketPeer> get_peer(int p_id) const; + IP_Address get_peer_address(int p_peer_id) const; + int get_peer_port(int p_peer_id) const; + void disconnect_peer(int p_peer_id); virtual void poll(); virtual PoolVector<String> get_protocols() const; diff --git a/modules/websocket/lws_peer.cpp b/modules/websocket/lws_peer.cpp index ba45d7688f..8a064fb5a4 100644 --- a/modules/websocket/lws_peer.cpp +++ b/modules/websocket/lws_peer.cpp @@ -32,6 +32,13 @@ #include "lws_peer.h" #include "core/io/ip.h" +// Needed for socket_helpers on Android at least. UNIXes has it, just include if not windows +#if !defined(WINDOWS_ENABLED) +#include <netinet/in.h> +#endif + +#include "drivers/unix/socket_helpers.h" + void LWSPeer::set_wsi(struct lws *p_wsi) { wsi = p_wsi; }; @@ -178,12 +185,40 @@ void LWSPeer::close() { IP_Address LWSPeer::get_connected_host() const { - return IP_Address(); + ERR_FAIL_COND_V(!is_connected_to_host(), IP_Address()); + + IP_Address ip; + int port = 0; + + socklen_t len; + struct sockaddr_storage addr; + int fd = lws_get_socket_fd(wsi); + + int ret = getpeername(fd, (struct sockaddr *)&addr, &len); + ERR_FAIL_COND_V(ret != 0, IP_Address()); + + _set_ip_addr_port(ip, port, &addr); + + return ip; }; uint16_t LWSPeer::get_connected_port() const { - return 1025; + ERR_FAIL_COND_V(!is_connected_to_host(), 0); + + IP_Address ip; + int port = 0; + + socklen_t len; + struct sockaddr_storage addr; + int fd = lws_get_socket_fd(wsi); + + int ret = getpeername(fd, (struct sockaddr *)&addr, &len); + ERR_FAIL_COND_V(ret != 0, 0); + + _set_ip_addr_port(ip, port, &addr); + + return port; }; LWSPeer::LWSPeer() { diff --git a/modules/websocket/lws_server.cpp b/modules/websocket/lws_server.cpp index 94fe4231ae..8d13dc7a98 100644 --- a/modules/websocket/lws_server.cpp +++ b/modules/websocket/lws_server.cpp @@ -164,6 +164,24 @@ Ref<WebSocketPeer> LWSServer::get_peer(int p_id) const { return _peer_map[p_id]; } +IP_Address LWSServer::get_peer_address(int p_peer_id) const { + ERR_FAIL_COND_V(!has_peer(p_peer_id), IP_Address()); + + return _peer_map[p_peer_id]->get_connected_host(); +} + +int LWSServer::get_peer_port(int p_peer_id) const { + ERR_FAIL_COND_V(!has_peer(p_peer_id), 0); + + return _peer_map[p_peer_id]->get_connected_port(); +} + +void LWSServer::disconnect_peer(int p_peer_id) { + ERR_FAIL_COND(!has_peer(p_peer_id)); + + get_peer(p_peer_id)->close(); +} + LWSServer::LWSServer() { context = NULL; _lws_ref = NULL; diff --git a/modules/websocket/lws_server.h b/modules/websocket/lws_server.h index de8f59e5ae..9e3fb9b775 100644 --- a/modules/websocket/lws_server.h +++ b/modules/websocket/lws_server.h @@ -52,6 +52,9 @@ public: bool is_listening() const; bool has_peer(int p_id) const; Ref<WebSocketPeer> get_peer(int p_id) const; + IP_Address get_peer_address(int p_peer_id) const; + int get_peer_port(int p_peer_id) const; + void disconnect_peer(int p_peer_id); virtual void poll() { _lws_poll(); } LWSServer(); diff --git a/modules/websocket/websocket_peer.cpp b/modules/websocket/websocket_peer.cpp index 6324047846..61f783e377 100644 --- a/modules/websocket/websocket_peer.cpp +++ b/modules/websocket/websocket_peer.cpp @@ -43,6 +43,8 @@ void WebSocketPeer::_bind_methods() { ClassDB::bind_method(D_METHOD("is_connected_to_host"), &WebSocketPeer::is_connected_to_host); ClassDB::bind_method(D_METHOD("was_string_packet"), &WebSocketPeer::was_string_packet); ClassDB::bind_method(D_METHOD("close"), &WebSocketPeer::close); + ClassDB::bind_method(D_METHOD("get_connected_host"), &WebSocketPeer::get_connected_host); + ClassDB::bind_method(D_METHOD("get_connected_port"), &WebSocketPeer::get_connected_port); BIND_ENUM_CONSTANT(WRITE_MODE_TEXT); BIND_ENUM_CONSTANT(WRITE_MODE_BINARY); diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp index 5746f61e10..2693b26e47 100644 --- a/modules/websocket/websocket_server.cpp +++ b/modules/websocket/websocket_server.cpp @@ -44,6 +44,9 @@ void WebSocketServer::_bind_methods() { ClassDB::bind_method(D_METHOD("listen", "port", "protocols", "gd_mp_api"), &WebSocketServer::listen, DEFVAL(PoolVector<String>()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("stop"), &WebSocketServer::stop); ClassDB::bind_method(D_METHOD("has_peer", "id"), &WebSocketServer::has_peer); + ClassDB::bind_method(D_METHOD("get_peer_address"), &WebSocketServer::get_peer_address); + ClassDB::bind_method(D_METHOD("get_peer_port"), &WebSocketServer::get_peer_port); + ClassDB::bind_method(D_METHOD("disconnect_peer"), &WebSocketServer::disconnect_peer); ADD_SIGNAL(MethodInfo("client_disconnected", PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("client_connected", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::STRING, "protocol"))); diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h index 360ff9e6d4..64935f8a58 100644 --- a/modules/websocket/websocket_server.h +++ b/modules/websocket/websocket_server.h @@ -52,6 +52,10 @@ public: virtual bool is_server() const; ConnectionStatus get_connection_status() const; + virtual IP_Address get_peer_address(int p_peer_id) const = 0; + virtual int get_peer_port(int p_peer_id) const = 0; + virtual void disconnect_peer(int p_peer_id) = 0; + void _on_peer_packet(int32_t p_peer_id); void _on_connect(int32_t p_peer_id, String p_protocol); void _on_disconnect(int32_t p_peer_id); |