summaryrefslogtreecommitdiff
path: root/core/io
diff options
context:
space:
mode:
Diffstat (limited to 'core/io')
-rw-r--r--core/io/SCsub3
-rw-r--r--core/io/http_client.cpp4
-rw-r--r--core/io/marshalls.cpp1
-rw-r--r--core/io/multiplayer_api.cpp165
-rw-r--r--core/io/resource_format_binary.cpp2
-rw-r--r--core/io/zip_io.cpp137
-rw-r--r--core/io/zip_io.h112
7 files changed, 261 insertions, 163 deletions
diff --git a/core/io/SCsub b/core/io/SCsub
index 79b56cb716..1c5f954470 100644
--- a/core/io/SCsub
+++ b/core/io/SCsub
@@ -3,6 +3,3 @@
Import('env')
env.add_source_files(env.core_sources, "*.cpp")
-
-Export('env')
-
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index ac563df0c3..36dd688e77 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -374,6 +374,7 @@ Error HTTPClient::poll() {
} break;
}
} break;
+ case STATUS_BODY:
case STATUS_CONNECTED: {
// Check if we are still connected
if (ssl) {
@@ -480,7 +481,8 @@ Error HTTPClient::poll() {
case STATUS_DISCONNECTED: {
return ERR_UNCONFIGURED;
} break;
- case STATUS_CONNECTION_ERROR: {
+ case STATUS_CONNECTION_ERROR:
+ case STATUS_SSL_HANDSHAKE_ERROR: {
return ERR_CONNECTION_ERROR;
} break;
case STATUS_CANT_CONNECT: {
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index e15519da47..d33d436b74 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -824,6 +824,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
flags |= ENCODE_FLAG_OBJECT_AS_ID;
}
} break;
+ default: {} // nothing to do at this stage
}
if (buf) {
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index 5503b8d59c..17b77bc535 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -38,20 +38,23 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas
switch (mode) {
case MultiplayerAPI::RPC_MODE_DISABLED: {
- //do nothing
+ // Do nothing.
} break;
case MultiplayerAPI::RPC_MODE_REMOTE: {
- //do nothing also, no need to call local
+ // Do nothing also. Remote cannot produce a local call.
} break;
+ case MultiplayerAPI::RPC_MODE_MASTERSYNC: {
+ if (is_master)
+ r_skip_rpc = true; // I am the master, so skip remote call.
+ } // Do not break, fall over to other sync.
case MultiplayerAPI::RPC_MODE_REMOTESYNC:
- case MultiplayerAPI::RPC_MODE_MASTERSYNC:
case MultiplayerAPI::RPC_MODE_PUPPETSYNC: {
- //call it, sync always results in call
+ // Call it, sync always results in a local call.
return true;
} break;
case MultiplayerAPI::RPC_MODE_MASTER: {
if (is_master)
- r_skip_rpc = true; //no other master so..
+ r_skip_rpc = true; // I am the master, so skip remote call.
return is_master;
} break;
case MultiplayerAPI::RPC_MODE_PUPPET: {
@@ -91,7 +94,7 @@ void MultiplayerAPI::poll() {
network_peer->poll();
- if (!network_peer.is_valid()) //it's possible that polling might have resulted in a disconnection, so check here
+ if (!network_peer.is_valid()) // It's possible that polling might have resulted in a disconnection, so check here.
return;
while (network_peer->get_available_packet_count()) {
@@ -110,7 +113,7 @@ void MultiplayerAPI::poll() {
rpc_sender_id = 0;
if (!network_peer.is_valid()) {
- break; //it's also possible that a packet or RPC caused a disconnection, so also check here
+ break; // It's also possible that a packet or RPC caused a disconnection, so also check here.
}
}
}
@@ -157,7 +160,9 @@ Ref<NetworkedMultiplayerPeer> MultiplayerAPI::get_network_peer() const {
void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_packet_len) {
+ ERR_EXPLAIN("Multiplayer root node was not initialized. If you are using custom multiplayer, remember to set the root node via MultiplayerAPI.set_root_node before using it");
ERR_FAIL_COND(root_node == NULL);
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_packet_len < 1);
uint8_t packet_type = p_packet[0];
@@ -177,13 +182,15 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
case NETWORK_COMMAND_REMOTE_CALL:
case NETWORK_COMMAND_REMOTE_SET: {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_packet_len < 6);
Node *node = _process_get_node(p_from, p_packet, p_packet_len);
+ ERR_EXPLAIN("Invalid packet received. Requested node was not found.");
ERR_FAIL_COND(node == NULL);
- //detect cstring end
+ // Detect cstring end.
int len_end = 5;
for (; len_end < p_packet_len; len_end++) {
if (p_packet[len_end] == 0) {
@@ -191,6 +198,7 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
}
}
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(len_end >= p_packet_len);
StringName name = String::utf8((const char *)&p_packet[5]);
@@ -219,9 +227,11 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, int
Node *node = NULL;
if (target & 0x80000000) {
- //use full path (not cached yet)
+ // Use full path (not cached yet).
int ofs = target & 0x7FFFFFFF;
+
+ ERR_EXPLAIN("Invalid packet received. Size smaller than declared.");
ERR_FAIL_COND_V(ofs >= p_packet_len, NULL);
String paths;
@@ -234,17 +244,19 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, int
if (!node)
ERR_PRINTS("Failed to get path from RPC: " + String(np));
} else {
- //use cached path
+ // Use cached path.
int id = target;
Map<int, PathGetCache>::Element *E = path_get_cache.find(p_from);
+ ERR_EXPLAIN("Invalid packet received. Requests invalid peer cache.");
ERR_FAIL_COND_V(!E, NULL);
Map<int, PathGetCache::NodeInfo>::Element *F = E->get().nodes.find(id);
+ ERR_EXPLAIN("Invalid packet received. Unabled to find requested cached node.");
ERR_FAIL_COND_V(!F, NULL);
PathGetCache::NodeInfo *ni = &F->get();
- //do proper caching later
+ // Do proper caching later.
node = root_node->get_node(ni->path);
if (!node)
@@ -255,9 +267,10 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, int
void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_offset >= p_packet_len);
- // Check that remote can call the RPC on this node
+ // Check that remote can call the RPC on this node.
RPCMode rpc_mode = RPC_MODE_DISABLED;
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rpc_mode(p_name);
if (E) {
@@ -265,6 +278,8 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
} else if (p_node->get_script_instance()) {
rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_name);
}
+
+ ERR_EXPLAIN("RPC '" + String(p_name) + "' is not allowed from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
ERR_FAIL_COND(!_can_call_mode(p_node, rpc_mode, p_from));
int argc = p_packet[p_offset];
@@ -277,11 +292,14 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
for (int i = 0; i < argc; i++) {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_offset >= p_packet_len);
+
int vlen;
Error err = decode_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen);
+ ERR_EXPLAIN("Invalid packet received. Unable to decode RPC argument.");
ERR_FAIL_COND(err != OK);
- //args[i]=p_packet[3+i];
+
argp.write[i] = &args[i];
p_offset += vlen;
}
@@ -298,9 +316,10 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_offset >= p_packet_len);
- // Check that remote can call the RSET on this node
+ // Check that remote can call the RSET on this node.
RPCMode rset_mode = RPC_MODE_DISABLED;
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rset_mode(p_name);
if (E) {
@@ -308,10 +327,15 @@ void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p
} else if (p_node->get_script_instance()) {
rset_mode = p_node->get_script_instance()->get_rset_mode(p_name);
}
+
+ ERR_EXPLAIN("RSET '" + String(p_name) + "' is not allowed from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
ERR_FAIL_COND(!_can_call_mode(p_node, rset_mode, p_from));
Variant value;
- decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset);
+ Error err = decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset);
+
+ ERR_EXPLAIN("Invalid packet received. Unable to decode RSET value.");
+ ERR_FAIL_COND(err != OK);
bool valid;
@@ -324,6 +348,7 @@ void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p
void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_packet_len < 5);
int id = decode_uint32(&p_packet[1]);
@@ -342,9 +367,7 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
path_get_cache[p_from].nodes[id] = ni;
- //send ack
-
- //encode path
+ // Encode path to send ack.
CharString pname = String(path).utf8();
int len = encode_cstring(pname.get_data(), NULL);
@@ -361,6 +384,7 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
void MultiplayerAPI::_process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_packet_len < 2);
String paths;
@@ -369,31 +393,33 @@ void MultiplayerAPI::_process_confirm_path(int p_from, const uint8_t *p_packet,
NodePath path = paths;
PathSentCache *psc = path_send_cache.getptr(path);
+ ERR_EXPLAIN("Invalid packet received. Tries to confirm a path which was not found in cache.");
ERR_FAIL_COND(!psc);
Map<int, bool>::Element *E = psc->confirmed_peers.find(p_from);
+ ERR_EXPLAIN("Invalid packet received. Source peer was not found in cache for the given path.");
ERR_FAIL_COND(!E);
E->get() = true;
}
bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int p_target) {
bool has_all_peers = true;
- List<int> peers_to_add; //if one is missing, take note to add it
+ List<int> peers_to_add; // If one is missing, take note to add it.
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
if (p_target < 0 && E->get() == -p_target)
- continue; //continue, excluded
+ continue; // Continue, excluded.
if (p_target > 0 && E->get() != p_target)
- continue; //continue, not for this peer
+ continue; // Continue, not for this peer.
Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
if (!F || F->get() == false) {
- //path was not cached, or was cached but is unconfirmed
+ // Path was not cached, or was cached but is unconfirmed.
if (!F) {
- //not cached at all, take note
+ // Not cached at all, take note.
peers_to_add.push_back(E->get());
}
@@ -401,11 +427,11 @@ bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int
}
}
- //those that need to be added, send a message for this
+ // Those that need to be added, send a message for this.
for (List<int>::Element *E = peers_to_add.front(); E; E = E->next()) {
- //encode function name
+ // Encode function name.
CharString pname = String(p_path).utf8();
int len = encode_cstring(pname.get_data(), NULL);
@@ -416,11 +442,11 @@ bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int
encode_uint32(psc->id, &packet.write[1]);
encode_cstring(pname.get_data(), &packet.write[5]);
- network_peer->set_target_peer(E->get()); //to all of you
+ network_peer->set_target_peer(E->get()); // To all of you.
network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
network_peer->put_packet(packet.ptr(), packet.size());
- psc->confirmed_peers.insert(E->get(), false); //insert into confirmed, but as false since it was not confirmed
+ psc->confirmed_peers.insert(E->get(), false); // Insert into confirmed, but as false since it was not confirmed.
}
return has_all_peers;
@@ -459,35 +485,36 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
}
NodePath from_path = (root_node->get_path()).rel_path_to(p_from->get_path());
+ ERR_EXPLAIN("Unable to send RPC. Relative path is empty. THIS IS LIKELY A BUG IN THE ENGINE!");
ERR_FAIL_COND(from_path.is_empty());
- //see if the path is cached
+ // See if the path is cached.
PathSentCache *psc = path_send_cache.getptr(from_path);
if (!psc) {
- //path is not cached, create
+ // Path is not cached, create.
path_send_cache[from_path] = PathSentCache();
psc = path_send_cache.getptr(from_path);
psc->id = last_send_cache_id++;
}
- //create base packet, lots of hardcode because it must be tight
+ // Create base packet, lots of hardcode because it must be tight.
int ofs = 0;
#define MAKE_ROOM(m_amount) \
if (packet_cache.size() < m_amount) packet_cache.resize(m_amount);
- //encode type
+ // Encode type.
MAKE_ROOM(1);
packet_cache.write[0] = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL;
ofs += 1;
- //encode ID
+ // Encode ID.
MAKE_ROOM(ofs + 4);
encode_uint32(psc->id, &(packet_cache.write[ofs]));
ofs += 4;
- //encode function name
+ // Encode function name.
CharString name = String(p_name).utf8();
int len = encode_cstring(name.get_data(), NULL);
MAKE_ROOM(ofs + len);
@@ -495,20 +522,22 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
ofs += len;
if (p_set) {
- //set argument
+ // Set argument.
Error err = encode_variant(*p_arg[0], NULL, len);
+ ERR_EXPLAIN("Unable to encode RSET value. THIS IS LIKELY A BUG IN THE ENGINE!");
ERR_FAIL_COND(err != OK);
MAKE_ROOM(ofs + len);
encode_variant(*p_arg[0], &(packet_cache.write[ofs]), len);
ofs += len;
} else {
- //call arguments
+ // Call arguments.
MAKE_ROOM(ofs + 1);
packet_cache.write[ofs] = p_argcount;
ofs += 1;
for (int i = 0; i < p_argcount; i++) {
Error err = encode_variant(*p_arg[i], NULL, len);
+ ERR_EXPLAIN("Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!");
ERR_FAIL_COND(err != OK);
MAKE_ROOM(ofs + len);
encode_variant(*p_arg[i], &(packet_cache.write[ofs]), len);
@@ -516,21 +545,21 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
}
}
- //see if all peers have cached path (is so, call can be fast)
+ // See if all peers have cached path (is so, call can be fast).
bool has_all_peers = _send_confirm_path(from_path, psc, p_to);
- //take chance and set transfer mode, since all send methods will use it
+ // Take chance and set transfer mode, since all send methods will use it.
network_peer->set_transfer_mode(p_unreliable ? NetworkedMultiplayerPeer::TRANSFER_MODE_UNRELIABLE : NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
if (has_all_peers) {
- //they all have verified paths, so send fast
- network_peer->set_target_peer(p_to); //to all of you
- network_peer->put_packet(packet_cache.ptr(), ofs); //a message with love
+ // They all have verified paths, so send fast.
+ network_peer->set_target_peer(p_to); // To all of you.
+ network_peer->put_packet(packet_cache.ptr(), ofs); // A message with love.
} else {
- //not all verified path, so send one by one
+ // Not all verified path, so send one by one.
- //apend path at the end, since we will need it for some packets
+ // Append path at the end, since we will need it for some packets.
CharString pname = String(from_path).utf8();
int path_len = encode_cstring(pname.get_data(), NULL);
MAKE_ROOM(ofs + path_len);
@@ -539,23 +568,23 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
if (p_to < 0 && E->get() == -p_to)
- continue; //continue, excluded
+ continue; // Continue, excluded.
if (p_to > 0 && E->get() != p_to)
- continue; //continue, not for this peer
+ continue; // Continue, not for this peer.
Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
- ERR_CONTINUE(!F); //should never happen
+ ERR_CONTINUE(!F); // Should never happen.
- network_peer->set_target_peer(E->get()); //to this one specifically
+ network_peer->set_target_peer(E->get()); // To this one specifically.
if (F->get() == true) {
- //this one confirmed path, so use id
+ // This one confirmed path, so use id.
encode_uint32(psc->id, &(packet_cache.write[1]));
network_peer->put_packet(packet_cache.ptr(), ofs);
} else {
- //this one did not confirm path yet, so use entire path (sorry!)
- encode_uint32(0x80000000 | ofs, &(packet_cache.write[1])); //offset to path and flag
+ // This one did not confirm path yet, so use entire path (sorry!).
+ encode_uint32(0x80000000 | ofs, &(packet_cache.write[1])); // Offset to path and flag.
network_peer->put_packet(packet_cache.ptr(), ofs + path_len);
}
}
@@ -570,7 +599,7 @@ void MultiplayerAPI::_add_peer(int p_id) {
void MultiplayerAPI::_del_peer(int p_id) {
connected_peers.erase(p_id);
- path_get_cache.erase(p_id); //I no longer need your cache, sorry
+ path_get_cache.erase(p_id); // I no longer need your cache, sorry.
emit_signal("network_peer_disconnected", p_id);
}
@@ -591,8 +620,12 @@ void MultiplayerAPI::_server_disconnected() {
void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount) {
- ERR_FAIL_COND(!p_node->is_inside_tree());
+ ERR_EXPLAIN("Trying to call an RPC while no network peer is active.");
ERR_FAIL_COND(!network_peer.is_valid());
+ ERR_EXPLAIN("Trying to call an RPC on a node which is not inside SceneTree.");
+ ERR_FAIL_COND(!p_node->is_inside_tree());
+ ERR_EXPLAIN("Trying to call an RPC via a network peer which is not connected.");
+ ERR_FAIL_COND(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED);
int node_id = network_peer->get_unique_id();
bool skip_rpc = false;
@@ -601,7 +634,7 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
bool is_master = p_node->is_network_master();
if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) {
- //check that send mode can use local call
+ // Check that send mode can use local call.
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rpc_mode(p_method);
if (E) {
@@ -609,9 +642,9 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
}
if (call_local_native) {
- // done below
+ // Done below.
} else if (p_node->get_script_instance()) {
- //attempt with script
+ // Attempt with script.
RPCMode rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_method);
call_local_script = _should_call_local(rpc_mode, is_master, skip_rpc);
}
@@ -647,15 +680,19 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) {
- ERR_FAIL_COND(!p_node->is_inside_tree());
+ ERR_EXPLAIN("Trying to RSET while no network peer is active.");
ERR_FAIL_COND(!network_peer.is_valid());
+ ERR_EXPLAIN("Trying to RSET on a node which is not inside SceneTree.");
+ ERR_FAIL_COND(!p_node->is_inside_tree());
+ ERR_EXPLAIN("Trying to send an RSET via a network peer which is not connected.");
+ ERR_FAIL_COND(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED);
int node_id = network_peer->get_unique_id();
bool is_master = p_node->is_network_master();
bool skip_rset = false;
if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) {
- //check that send mode can use local call
+ // Check that send mode can use local call.
bool set_local = false;
@@ -675,7 +712,7 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
return;
}
} else if (p_node->get_script_instance()) {
- //attempt with script
+ // Attempt with script.
RPCMode rpc_mode = p_node->get_script_instance()->get_rset_mode(p_property);
set_local = _should_call_local(rpc_mode, is_master, skip_rset);
@@ -703,8 +740,11 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
Error MultiplayerAPI::send_bytes(PoolVector<uint8_t> p_data, int p_to, NetworkedMultiplayerPeer::TransferMode p_mode) {
+ ERR_EXPLAIN("Trying to send an empty raw packet.");
ERR_FAIL_COND_V(p_data.size() < 1, ERR_INVALID_DATA);
+ ERR_EXPLAIN("Trying to send a raw packet while no network peer is active.");
ERR_FAIL_COND_V(!network_peer.is_valid(), ERR_UNCONFIGURED);
+ ERR_EXPLAIN("Trying to send a raw packet via a network peer which is not connected.");
ERR_FAIL_COND_V(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED);
MAKE_ROOM(p_data.size() + 1);
@@ -720,6 +760,7 @@ Error MultiplayerAPI::send_bytes(PoolVector<uint8_t> p_data, int p_to, Networked
void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_packet_len) {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_packet_len < 2);
PoolVector<uint8_t> out;
@@ -734,30 +775,36 @@ void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_pac
int MultiplayerAPI::get_network_unique_id() const {
+ ERR_EXPLAIN("No network peer is assigned. Unable to get unique network ID.");
ERR_FAIL_COND_V(!network_peer.is_valid(), 0);
return network_peer->get_unique_id();
}
bool MultiplayerAPI::is_network_server() const {
+ // XXX Maybe fail silently? Maybe should actually return true to make development of both local and online multiplayer easier?
+ ERR_EXPLAIN("No network peer is assigned. I can't be a server.");
ERR_FAIL_COND_V(!network_peer.is_valid(), false);
return network_peer->is_server();
}
void MultiplayerAPI::set_refuse_new_network_connections(bool p_refuse) {
+ ERR_EXPLAIN("No network peer is assigned. Unable to set 'refuse_new_connections'.");
ERR_FAIL_COND(!network_peer.is_valid());
network_peer->set_refuse_new_connections(p_refuse);
}
bool MultiplayerAPI::is_refusing_new_network_connections() const {
+ ERR_EXPLAIN("No network peer is assigned. Unable to get 'refuse_new_connections'.");
ERR_FAIL_COND_V(!network_peer.is_valid(), false);
return network_peer->is_refusing_new_connections();
}
Vector<int> MultiplayerAPI::get_network_connected_peers() const {
+ ERR_EXPLAIN("No network peer is assigned. Assume no peers are connected.");
ERR_FAIL_COND_V(!network_peer.is_valid(), Vector<int>());
Vector<int> ret;
@@ -802,9 +849,9 @@ void MultiplayerAPI::_bind_methods() {
BIND_ENUM_CONSTANT(RPC_MODE_REMOTE);
BIND_ENUM_CONSTANT(RPC_MODE_MASTER);
BIND_ENUM_CONSTANT(RPC_MODE_PUPPET);
- BIND_ENUM_CONSTANT(RPC_MODE_SLAVE); // deprecated
+ BIND_ENUM_CONSTANT(RPC_MODE_SLAVE); // Deprecated.
BIND_ENUM_CONSTANT(RPC_MODE_REMOTESYNC);
- BIND_ENUM_CONSTANT(RPC_MODE_SYNC); // deprecated
+ BIND_ENUM_CONSTANT(RPC_MODE_SYNC); // Deprecated.
BIND_ENUM_CONSTANT(RPC_MODE_MASTERSYNC);
BIND_ENUM_CONSTANT(RPC_MODE_PUPPETSYNC);
}
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 02c2c6ce1a..e5741014a4 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -1718,7 +1718,7 @@ void ResourceFormatSaverBinaryInstance::save_unicode_string(FileAccess *f, const
CharString utf8 = p_string.utf8();
if (p_bit_on_len) {
- f->store_32(utf8.length() + 1 | 0x80000000);
+ f->store_32((utf8.length() + 1) | 0x80000000);
} else {
f->store_32(utf8.length() + 1);
}
diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp
new file mode 100644
index 0000000000..b7f841b66f
--- /dev/null
+++ b/core/io/zip_io.cpp
@@ -0,0 +1,137 @@
+/*************************************************************************/
+/* zip_io.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "zip_io.h"
+
+#include "core/os/copymem.h"
+
+void *zipio_open(void *data, const char *p_fname, int mode) {
+
+ FileAccess *&f = *(FileAccess **)data;
+
+ String fname;
+ fname.parse_utf8(p_fname);
+
+ if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
+ f = FileAccess::open(fname, FileAccess::WRITE);
+ } else {
+
+ f = FileAccess::open(fname, FileAccess::READ);
+ }
+
+ if (!f)
+ return NULL;
+
+ return data;
+}
+
+uLong zipio_read(void *data, void *fdata, void *buf, uLong size) {
+
+ FileAccess *f = *(FileAccess **)data;
+ return f->get_buffer((uint8_t *)buf, size);
+}
+
+uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
+
+ FileAccess *f = *(FileAccess **)opaque;
+ f->store_buffer((uint8_t *)buf, size);
+ return size;
+}
+
+long zipio_tell(voidpf opaque, voidpf stream) {
+
+ FileAccess *f = *(FileAccess **)opaque;
+ return f->get_position();
+}
+
+long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
+
+ FileAccess *f = *(FileAccess **)opaque;
+
+ int pos = offset;
+ switch (origin) {
+
+ case ZLIB_FILEFUNC_SEEK_CUR:
+ pos = f->get_position() + offset;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END:
+ pos = f->get_len() + offset;
+ break;
+ default:
+ break;
+ };
+
+ f->seek(pos);
+ return 0;
+}
+
+int zipio_close(voidpf opaque, voidpf stream) {
+
+ FileAccess *&f = *(FileAccess **)opaque;
+ if (f) {
+ f->close();
+ f = NULL;
+ }
+ return 0;
+}
+
+int zipio_testerror(voidpf opaque, voidpf stream) {
+
+ FileAccess *f = *(FileAccess **)opaque;
+ return (f && f->get_error() != OK) ? 1 : 0;
+}
+
+voidpf zipio_alloc(voidpf opaque, uInt items, uInt size) {
+
+ voidpf ptr = memalloc(items * size);
+ zeromem(ptr, items * size);
+ return ptr;
+}
+
+void zipio_free(voidpf opaque, voidpf address) {
+
+ memfree(address);
+}
+
+zlib_filefunc_def zipio_create_io_from_file(FileAccess **p_file) {
+
+ zlib_filefunc_def io;
+ io.opaque = p_file;
+ io.zopen_file = zipio_open;
+ io.zread_file = zipio_read;
+ io.zwrite_file = zipio_write;
+ io.ztell_file = zipio_tell;
+ io.zseek_file = zipio_seek;
+ io.zclose_file = zipio_close;
+ io.zerror_file = zipio_testerror;
+ io.alloc_mem = zipio_alloc;
+ io.free_mem = zipio_free;
+ return io;
+}
diff --git a/core/io/zip_io.h b/core/io/zip_io.h
index c3314a8990..bba7d67332 100644
--- a/core/io/zip_io.h
+++ b/core/io/zip_io.h
@@ -31,114 +31,28 @@
#ifndef ZIP_IO_H
#define ZIP_IO_H
-#include "core/os/copymem.h"
#include "core/os/file_access.h"
+// Not direclty used in this header, but assumed available in downstream users
+// like platform/*/export/export.cpp. Could be fixed, but probably better to have
+// thirdparty includes in as little headers as possible.
#include "thirdparty/minizip/unzip.h"
#include "thirdparty/minizip/zip.h"
-static void *zipio_open(void *data, const char *p_fname, int mode) {
+void *zipio_open(void *data, const char *p_fname, int mode);
+uLong zipio_read(void *data, void *fdata, void *buf, uLong size);
+uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size);
- FileAccess *&f = *(FileAccess **)data;
+long zipio_tell(voidpf opaque, voidpf stream);
+long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin);
- String fname;
- fname.parse_utf8(p_fname);
+int zipio_close(voidpf opaque, voidpf stream);
- if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
- f = FileAccess::open(fname, FileAccess::WRITE);
- } else {
+int zipio_testerror(voidpf opaque, voidpf stream);
- f = FileAccess::open(fname, FileAccess::READ);
- }
+voidpf zipio_alloc(voidpf opaque, uInt items, uInt size);
+void zipio_free(voidpf opaque, voidpf address);
- if (!f)
- return NULL;
-
- return data;
-};
-
-static uLong zipio_read(void *data, void *fdata, void *buf, uLong size) {
-
- FileAccess *f = *(FileAccess **)data;
- return f->get_buffer((uint8_t *)buf, size);
-};
-
-static uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
-
- FileAccess *f = *(FileAccess **)opaque;
- f->store_buffer((uint8_t *)buf, size);
- return size;
-};
-
-static long zipio_tell(voidpf opaque, voidpf stream) {
-
- FileAccess *f = *(FileAccess **)opaque;
- return f->get_position();
-};
-
-static long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
-
- FileAccess *f = *(FileAccess **)opaque;
-
- int pos = offset;
- switch (origin) {
-
- case ZLIB_FILEFUNC_SEEK_CUR:
- pos = f->get_position() + offset;
- break;
- case ZLIB_FILEFUNC_SEEK_END:
- pos = f->get_len() + offset;
- break;
- default:
- break;
- };
-
- f->seek(pos);
- return 0;
-};
-
-static int zipio_close(voidpf opaque, voidpf stream) {
-
- FileAccess *&f = *(FileAccess **)opaque;
- if (f) {
- f->close();
- f = NULL;
- }
- return 0;
-};
-
-static int zipio_testerror(voidpf opaque, voidpf stream) {
-
- FileAccess *f = *(FileAccess **)opaque;
- return (f && f->get_error() != OK) ? 1 : 0;
-};
-
-static voidpf zipio_alloc(voidpf opaque, uInt items, uInt size) {
-
- voidpf ptr = memalloc(items * size);
- zeromem(ptr, items * size);
- return ptr;
-}
-
-static void zipio_free(voidpf opaque, voidpf address) {
-
- memfree(address);
-}
-
-static zlib_filefunc_def zipio_create_io_from_file(FileAccess **p_file) {
-
- zlib_filefunc_def io;
- io.opaque = p_file;
- io.zopen_file = zipio_open;
- io.zread_file = zipio_read;
- io.zwrite_file = zipio_write;
- io.ztell_file = zipio_tell;
- io.zseek_file = zipio_seek;
- io.zclose_file = zipio_close;
- io.zerror_file = zipio_testerror;
- io.alloc_mem = zipio_alloc;
- io.free_mem = zipio_free;
- return io;
-}
+zlib_filefunc_def zipio_create_io_from_file(FileAccess **p_file);
#endif // ZIP_IO_H