diff options
Diffstat (limited to 'core/io')
45 files changed, 781 insertions, 690 deletions
diff --git a/core/io/compression.cpp b/core/io/compression.cpp index 980234cbfc..6de626db99 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -32,7 +32,6 @@ #include "core/config/project_settings.h" #include "core/io/zip_io.h" -#include "core/os/copymem.h" #include "thirdparty/misc/fastlz.h" @@ -44,8 +43,8 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, case MODE_FASTLZ: { if (p_src_size < 16) { uint8_t src[16]; - zeromem(&src[p_src_size], 16 - p_src_size); - copymem(src, p_src, p_src_size); + memset(&src[p_src_size], 0, 16 - p_src_size); + memcpy(src, p_src, p_src_size); return fastlz_compress(src, 16, p_dst); } else { return fastlz_compress(p_src, p_src_size, p_dst); @@ -136,7 +135,7 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p if (p_dst_max_size < 16) { uint8_t dst[16]; ret_size = fastlz_decompress(p_src, p_src_size, dst, 16); - copymem(p_dst, dst, p_dst_max_size); + memcpy(p_dst, dst, p_dst_max_size); } else { ret_size = fastlz_decompress(p_src, p_src_size, p_dst, p_dst_max_size); } diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index b2440629e3..e54c947340 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -32,7 +32,7 @@ #include "core/string/print_string.h" -void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_mode, int p_block_size) { +void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_mode, uint32_t p_block_size) { magic = p_magic.ascii().get_data(); if (magic.length() > 4) { magic = magic.substr(0, 4); @@ -67,10 +67,10 @@ Error FileAccessCompressed::open_after_magic(FileAccess *p_base) { ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Can't open compressed file '" + p_base->get_path() + "' with block size 0, it is corrupted."); } read_total = f->get_32(); - int bc = (read_total / block_size) + 1; - int acc_ofs = f->get_position() + bc * 4; - int max_bs = 0; - for (int i = 0; i < bc; i++) { + uint32_t bc = (read_total / block_size) + 1; + uint64_t acc_ofs = f->get_position() + bc * 4; + uint32_t max_bs = 0; + for (uint32_t i = 0; i < bc; i++) { ReadBlock rb; rb.offset = acc_ofs; rb.csize = f->get_32(); @@ -148,15 +148,15 @@ void FileAccessCompressed::close() { f->store_32(cmode); //write compression mode 4 f->store_32(block_size); //write block size 4 f->store_32(write_max); //max amount of data written 4 - int bc = (write_max / block_size) + 1; + uint32_t bc = (write_max / block_size) + 1; - for (int i = 0; i < bc; i++) { + for (uint32_t i = 0; i < bc; i++) { f->store_32(0); //compressed sizes, will update later } Vector<int> block_sizes; - for (int i = 0; i < bc; i++) { - int bl = i == (bc - 1) ? write_max % block_size : block_size; + for (uint32_t i = 0; i < bc; i++) { + uint32_t bl = i == (bc - 1) ? write_max % block_size : block_size; uint8_t *bp = &write_ptr[i * block_size]; Vector<uint8_t> cblock; @@ -168,7 +168,7 @@ void FileAccessCompressed::close() { } f->seek(16); //ok write block sizes - for (int i = 0; i < bc; i++) { + for (uint32_t i = 0; i < bc; i++) { f->store_32(block_sizes[i]); } f->seek_end(); @@ -190,8 +190,9 @@ bool FileAccessCompressed::is_open() const { return f != nullptr; } -void FileAccessCompressed::seek(size_t p_position) { +void FileAccessCompressed::seek(uint64_t p_position) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); + if (writing) { ERR_FAIL_COND(p_position > write_max); @@ -204,7 +205,7 @@ void FileAccessCompressed::seek(size_t p_position) { } else { at_end = false; read_eof = false; - int block_idx = p_position / block_size; + uint32_t block_idx = p_position / block_size; if (block_idx != read_block) { read_block = block_idx; f->seek(read_blocks[read_block].offset); @@ -227,7 +228,7 @@ void FileAccessCompressed::seek_end(int64_t p_position) { } } -size_t FileAccessCompressed::get_position() const { +uint64_t FileAccessCompressed::get_position() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); if (writing) { return write_pos; @@ -236,7 +237,7 @@ size_t FileAccessCompressed::get_position() const { } } -size_t FileAccessCompressed::get_len() const { +uint64_t FileAccessCompressed::get_length() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); if (writing) { return write_max; @@ -285,9 +286,8 @@ uint8_t FileAccessCompressed::get_8() const { return ret; } -int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V_MSG(!f, -1, "File must be opened before use."); ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode."); @@ -296,7 +296,7 @@ int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const { return 0; } - for (int i = 0; i < p_length; i++) { + for (uint64_t i = 0; i < p_length; i++) { p_dst[i] = read_ptr[read_pos]; read_pos++; if (read_pos >= read_block_size) { diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h index 118d05ea57..19e4f241dd 100644 --- a/core/io/file_access_compressed.h +++ b/core/io/file_access_compressed.h @@ -37,34 +37,34 @@ class FileAccessCompressed : public FileAccess { Compression::Mode cmode = Compression::MODE_ZSTD; bool writing = false; - uint32_t write_pos = 0; + uint64_t write_pos = 0; uint8_t *write_ptr = nullptr; uint32_t write_buffer_size = 0; - uint32_t write_max = 0; + uint64_t write_max = 0; uint32_t block_size = 0; mutable bool read_eof = false; mutable bool at_end = false; struct ReadBlock { - int csize; - int offset; + uint32_t csize; + uint64_t offset; }; mutable Vector<uint8_t> comp_buffer; uint8_t *read_ptr = nullptr; - mutable int read_block = 0; - int read_block_count = 0; - mutable int read_block_size = 0; - mutable int read_pos = 0; + mutable uint32_t read_block = 0; + uint32_t read_block_count = 0; + mutable uint32_t read_block_size = 0; + mutable uint64_t read_pos = 0; Vector<ReadBlock> read_blocks; - uint32_t read_total = 0; + uint64_t read_total = 0; String magic = "GCMP"; mutable Vector<uint8_t> buffer; FileAccess *f = nullptr; public: - void configure(const String &p_magic, Compression::Mode p_mode = Compression::MODE_ZSTD, int p_block_size = 4096); + void configure(const String &p_magic, Compression::Mode p_mode = Compression::MODE_ZSTD, uint32_t p_block_size = 4096); Error open_after_magic(FileAccess *p_base); @@ -72,15 +72,15 @@ public: virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; virtual Error get_error() const; ///< get last error diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 8ace897f18..9e316291e8 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -31,7 +31,6 @@ #include "file_access_encrypted.h" #include "core/crypto/crypto_core.h" -#include "core/os/copymem.h" #include "core/string/print_string.h" #include "core/variant/variant.h" @@ -70,14 +69,14 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8 } base = p_base->get_position(); - ERR_FAIL_COND_V(p_base->get_len() < base + length, ERR_FILE_CORRUPT); - uint32_t ds = length; + ERR_FAIL_COND_V(p_base->get_length() < base + length, ERR_FILE_CORRUPT); + uint64_t ds = length; if (ds % 16) { ds += 16 - (ds % 16); } data.resize(ds); - uint32_t blen = p_base->get_buffer(data.ptrw(), ds); + uint64_t blen = p_base->get_buffer(data.ptrw(), ds); ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT); { @@ -142,7 +141,7 @@ void FileAccessEncrypted::release() { void FileAccessEncrypted::_release() { if (writing) { Vector<uint8_t> compressed; - size_t len = data.size(); + uint64_t len = data.size(); if (len % 16) { len += 16 - (len % 16); } @@ -151,7 +150,7 @@ void FileAccessEncrypted::_release() { ERR_FAIL_COND(CryptoCore::md5(data.ptr(), data.size(), hash) != OK); // Bug? compressed.resize(len); - zeromem(compressed.ptrw(), len); + memset(compressed.ptrw(), 0, len); for (int i = 0; i < data.size(); i++) { compressed.write[i] = data[i]; } @@ -199,9 +198,9 @@ String FileAccessEncrypted::get_path_absolute() const { } } -void FileAccessEncrypted::seek(size_t p_position) { - if (p_position > (size_t)data.size()) { - p_position = data.size(); +void FileAccessEncrypted::seek(uint64_t p_position) { + if (p_position > get_length()) { + p_position = get_length(); } pos = p_position; @@ -209,14 +208,14 @@ void FileAccessEncrypted::seek(size_t p_position) { } void FileAccessEncrypted::seek_end(int64_t p_position) { - seek(data.size() + p_position); + seek(get_length() + p_position); } -size_t FileAccessEncrypted::get_position() const { +uint64_t FileAccessEncrypted::get_position() const { return pos; } -size_t FileAccessEncrypted::get_len() const { +uint64_t FileAccessEncrypted::get_length() const { return data.size(); } @@ -226,7 +225,7 @@ bool FileAccessEncrypted::eof_reached() const { uint8_t FileAccessEncrypted::get_8() const { ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode."); - if (pos >= data.size()) { + if (pos >= get_length()) { eofed = true; return 0; } @@ -236,13 +235,12 @@ uint8_t FileAccessEncrypted::get_8() const { return b; } -int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessEncrypted::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode."); - int to_copy = MIN(p_length, data.size() - pos); - for (int i = 0; i < to_copy; i++) { + uint64_t to_copy = MIN(p_length, get_length() - pos); + for (uint64_t i = 0; i < to_copy; i++) { p_dst[i] = data[pos++]; } @@ -257,16 +255,17 @@ Error FileAccessEncrypted::get_error() const { return eofed ? ERR_FILE_EOF : OK; } -void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) { +void FileAccessEncrypted::store_buffer(const uint8_t *p_src, uint64_t p_length) { ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode."); + ERR_FAIL_COND(!p_src && p_length > 0); - if (pos < data.size()) { - for (int i = 0; i < p_length; i++) { + if (pos < get_length()) { + for (uint64_t i = 0; i < p_length; i++) { store_8(p_src[i]); } - } else if (pos == data.size()) { + } else if (pos == get_length()) { data.resize(pos + p_length); - for (int i = 0; i < p_length; i++) { + for (uint64_t i = 0; i < p_length; i++) { data.write[pos + i] = p_src[i]; } pos += p_length; @@ -282,10 +281,10 @@ void FileAccessEncrypted::flush() { void FileAccessEncrypted::store_8(uint8_t p_dest) { ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode."); - if (pos < data.size()) { + if (pos < get_length()) { data.write[pos] = p_dest; pos++; - } else if (pos == data.size()) { + } else if (pos == get_length()) { data.push_back(p_dest); pos++; } diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h index 969052d04f..00f14099f9 100644 --- a/core/io/file_access_encrypted.h +++ b/core/io/file_access_encrypted.h @@ -47,10 +47,10 @@ private: Vector<uint8_t> key; bool writing = false; FileAccess *file = nullptr; - size_t base = 0; - size_t length = 0; + uint64_t base = 0; + uint64_t length = 0; Vector<uint8_t> data; - mutable int pos = 0; + mutable uint64_t pos = 0; mutable bool eofed = false; bool use_magic = true; @@ -68,21 +68,21 @@ public: virtual String get_path() const; /// returns the path for the current open file virtual String get_path_absolute() const; /// returns the absolute path for the current open file - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; virtual Error get_error() const; ///< get last error virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte - virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes virtual bool file_exists(const String &p_name); ///< return true if a file exists diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index 58670d5246..d9be2a4a75 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -31,7 +31,6 @@ #include "file_access_memory.h" #include "core/config/project_settings.h" -#include "core/os/copymem.h" #include "core/os/dir_access.h" #include "core/templates/map.h" @@ -72,7 +71,7 @@ bool FileAccessMemory::file_exists(const String &p_name) { return files && (files->find(name) != nullptr); } -Error FileAccessMemory::open_custom(const uint8_t *p_data, int p_len) { +Error FileAccessMemory::open_custom(const uint8_t *p_data, uint64_t p_len) { data = (uint8_t *)p_data; length = p_len; pos = 0; @@ -103,7 +102,7 @@ bool FileAccessMemory::is_open() const { return data != nullptr; } -void FileAccessMemory::seek(size_t p_position) { +void FileAccessMemory::seek(uint64_t p_position) { ERR_FAIL_COND(!data); pos = p_position; } @@ -113,12 +112,12 @@ void FileAccessMemory::seek_end(int64_t p_position) { pos = length + p_position; } -size_t FileAccessMemory::get_position() const { +uint64_t FileAccessMemory::get_position() const { ERR_FAIL_COND_V(!data, 0); return pos; } -size_t FileAccessMemory::get_len() const { +uint64_t FileAccessMemory::get_length() const { ERR_FAIL_COND_V(!data, 0); return length; } @@ -137,19 +136,18 @@ uint8_t FileAccessMemory::get_8() const { return ret; } -int FileAccessMemory::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessMemory::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V(!data, -1); - int left = length - pos; - int read = MIN(p_length, left); + uint64_t left = length - pos; + uint64_t read = MIN(p_length, left); if (read < p_length) { WARN_PRINT("Reading less data than requested"); } - copymem(p_dst, &data[pos], read); + memcpy(p_dst, &data[pos], read); pos += p_length; return read; @@ -169,13 +167,14 @@ void FileAccessMemory::store_8(uint8_t p_byte) { data[pos++] = p_byte; } -void FileAccessMemory::store_buffer(const uint8_t *p_src, int p_length) { - int left = length - pos; - int write = MIN(p_length, left); +void FileAccessMemory::store_buffer(const uint8_t *p_src, uint64_t p_length) { + ERR_FAIL_COND(!p_src && p_length > 0); + uint64_t left = length - pos; + uint64_t write = MIN(p_length, left); if (write < p_length) { WARN_PRINT("Writing less data than requested"); } - copymem(&data[pos], p_src, write); + memcpy(&data[pos], p_src, write); pos += p_length; } diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h index 0e3b0ad7b1..4157531d01 100644 --- a/core/io/file_access_memory.h +++ b/core/io/file_access_memory.h @@ -35,8 +35,8 @@ class FileAccessMemory : public FileAccess { uint8_t *data = nullptr; - int length = 0; - mutable int pos = 0; + uint64_t length = 0; + mutable uint64_t pos = 0; static FileAccess *create(); @@ -44,27 +44,27 @@ public: static void register_file(String p_name, Vector<uint8_t> p_data); static void cleanup(); - virtual Error open_custom(const uint8_t *p_data, int p_len); ///< open a file + virtual Error open_custom(const uint8_t *p_data, uint64_t p_len); ///< open a file virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; ///< get an array of bytes + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; ///< get an array of bytes virtual Error get_error() const; ///< get last error virtual void flush(); virtual void store_8(uint8_t p_byte); ///< store a byte - virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes virtual bool file_exists(const String &p_name); ///< return true if a file exists diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index 31b7d658d0..63a8f9c5b6 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -126,7 +126,7 @@ void FileAccessNetworkClient::_thread_func() { if (status != OK) { fa->_respond(0, Error(status)); } else { - uint64_t len = get_64(); + int64_t len = get_64(); fa->_respond(len, Error(status)); } @@ -135,7 +135,7 @@ void FileAccessNetworkClient::_thread_func() { } break; case FileAccessNetwork::RESPONSE_DATA: { int64_t offset = get_64(); - uint32_t len = get_32(); + int32_t len = get_32(); Vector<uint8_t> block; block.resize(len); @@ -171,7 +171,7 @@ void FileAccessNetworkClient::_thread_func(void *s) { } Error FileAccessNetworkClient::connect(const String &p_host, int p_port, const String &p_password) { - IP_Address ip; + IPAddress ip; if (p_host.is_valid_ip_address()) { ip = p_host; @@ -219,13 +219,13 @@ FileAccessNetworkClient::~FileAccessNetworkClient() { thread.wait_to_finish(); } -void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block) { - int page = p_offset / page_size; +void FileAccessNetwork::_set_block(uint64_t p_offset, const Vector<uint8_t> &p_block) { + int32_t page = p_offset / page_size; ERR_FAIL_INDEX(page, pages.size()); if (page < pages.size() - 1) { ERR_FAIL_COND(p_block.size() != page_size); } else { - ERR_FAIL_COND((p_block.size() != (int)(total_size % page_size))); + ERR_FAIL_COND((uint64_t)p_block.size() != total_size % page_size); } { @@ -240,7 +240,7 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block) } } -void FileAccessNetwork::_respond(size_t p_len, Error p_status) { +void FileAccessNetwork::_respond(uint64_t p_len, Error p_status) { DEBUG_PRINT("GOT RESPONSE - len: " + itos(p_len) + " status: " + itos(p_status)); response = p_status; if (response != OK) { @@ -248,7 +248,7 @@ void FileAccessNetwork::_respond(size_t p_len, Error p_status) { } opened = true; total_size = p_len; - int pc = ((total_size - 1) / page_size) + 1; + int32_t pc = ((total_size - 1) / page_size) + 1; pages.resize(pc); } @@ -307,8 +307,9 @@ bool FileAccessNetwork::is_open() const { return opened; } -void FileAccessNetwork::seek(size_t p_position) { +void FileAccessNetwork::seek(uint64_t p_position) { ERR_FAIL_COND_MSG(!opened, "File must be opened before use."); + eof_flag = p_position > total_size; if (p_position >= total_size) { @@ -322,12 +323,12 @@ void FileAccessNetwork::seek_end(int64_t p_position) { seek(total_size + p_position); } -size_t FileAccessNetwork::get_position() const { +uint64_t FileAccessNetwork::get_position() const { ERR_FAIL_COND_V_MSG(!opened, 0, "File must be opened before use."); return pos; } -size_t FileAccessNetwork::get_len() const { +uint64_t FileAccessNetwork::get_length() const { ERR_FAIL_COND_V_MSG(!opened, 0, "File must be opened before use."); return total_size; } @@ -343,7 +344,7 @@ uint8_t FileAccessNetwork::get_8() const { return v; } -void FileAccessNetwork::_queue_page(int p_page) const { +void FileAccessNetwork::_queue_page(int32_t p_page) const { if (p_page >= pages.size()) { return; } @@ -354,7 +355,7 @@ void FileAccessNetwork::_queue_page(int p_page) const { FileAccessNetworkClient::BlockRequest br; br.id = id; - br.offset = size_t(p_page) * page_size; + br.offset = (uint64_t)p_page * page_size; br.size = page_size; nc->block_requests.push_back(br); pages.write[p_page].queued = true; @@ -365,11 +366,9 @@ void FileAccessNetwork::_queue_page(int p_page) const { } } -int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessNetwork::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); - //bool eof=false; if (pos + p_length > total_size) { eof_flag = true; } @@ -377,18 +376,16 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const { p_length = total_size - pos; } - //FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton; - uint8_t *buff = last_page_buff; - for (int i = 0; i < p_length; i++) { - int page = pos / page_size; + for (uint64_t i = 0; i < p_length; i++) { + int32_t page = pos / page_size; if (page != last_page) { buffer_mutex.lock(); if (pages[page].buffer.is_empty()) { waiting_on_page = page; - for (int j = 0; j < read_ahead; j++) { + for (int32_t j = 0; j < read_ahead; j++) { _queue_page(page + j); } buffer_mutex.unlock(); @@ -396,10 +393,9 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const { page_sem.wait(); DEBUG_PRINT("done"); } else { - for (int j = 0; j < read_ahead; j++) { + for (int32_t j = 0; j < read_ahead; j++) { _queue_page(page + j); } - //queue pages buffer_mutex.unlock(); } diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index 1f5de3e5dd..94b66c2480 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -40,9 +40,9 @@ class FileAccessNetwork; class FileAccessNetworkClient { struct BlockRequest { - int id; + int32_t id; uint64_t offset; - int size; + int32_t size; }; List<BlockRequest> block_requests; @@ -54,17 +54,17 @@ class FileAccessNetworkClient { Mutex blockrequest_mutex; Map<int, FileAccessNetwork *> accesses; Ref<StreamPeerTCP> client; - int last_id = 0; - int lockcount = 0; + int32_t last_id = 0; + int32_t lockcount = 0; Vector<uint8_t> block; void _thread_func(); static void _thread_func(void *s); - void put_32(int p_32); + void put_32(int32_t p_32); void put_64(int64_t p_64); - int get_32(); + int32_t get_32(); int64_t get_64(); void lock_mutex(); void unlock_mutex(); @@ -86,15 +86,15 @@ class FileAccessNetwork : public FileAccess { Semaphore page_sem; Mutex buffer_mutex; bool opened = false; - size_t total_size; - mutable size_t pos = 0; - int id; + uint64_t total_size; + mutable uint64_t pos = 0; + int32_t id; mutable bool eof_flag = false; - mutable int last_page = -1; + mutable int32_t last_page = -1; mutable uint8_t *last_page_buff = nullptr; - int page_size; - int read_ahead; + int32_t page_size; + int32_t read_ahead; mutable int waiting_on_page = -1; @@ -110,9 +110,9 @@ class FileAccessNetwork : public FileAccess { uint64_t exists_modtime; friend class FileAccessNetworkClient; - void _queue_page(int p_page) const; - void _respond(size_t p_len, Error p_status); - void _set_block(int p_offset, const Vector<uint8_t> &p_block); + void _queue_page(int32_t p_page) const; + void _respond(uint64_t p_len, Error p_status); + void _set_block(uint64_t p_offset, const Vector<uint8_t> &p_block); public: enum Command { @@ -134,15 +134,15 @@ public: virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; virtual Error get_error() const; ///< get last error diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index e24dc40166..7b43daf9c0 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -36,7 +36,7 @@ #include <stdio.h> -Error PackedData::add_pack(const String &p_path, bool p_replace_files, size_t p_offset) { +Error PackedData::add_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) { for (int i = 0; i < sources.size(); i++) { if (sources[i]->try_open_pack(p_path, p_replace_files, p_offset)) { return OK; @@ -46,17 +46,16 @@ Error PackedData::add_pack(const String &p_path, bool p_replace_files, size_t p_ return ERR_FILE_UNRECOGNIZED; } -void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted) { - PathMD5 pmd5(path.md5_buffer()); - //printf("adding path %s, %lli, %lli\n", path.utf8().get_data(), pmd5.a, pmd5.b); +void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64_t p_ofs, uint64_t p_size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted) { + PathMD5 pmd5(p_path.md5_buffer()); bool exists = files.has(pmd5); PackedFile pf; pf.encrypted = p_encrypted; - pf.pack = pkg_path; - pf.offset = ofs; - pf.size = size; + pf.pack = p_pkg_path; + pf.offset = p_ofs; + pf.size = p_size; for (int i = 0; i < 16; i++) { pf.md5[i] = p_md5[i]; } @@ -68,7 +67,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o if (!exists) { //search for dir - String p = path.replace_first("res://", ""); + String p = p_path.replace_first("res://", ""); PackedDir *cd = root; if (p.find("/") != -1) { //in a subdir @@ -87,7 +86,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o } } } - String filename = path.get_file(); + String filename = p_path.get_file(); // Don't add as a file if the path points to a directory if (!filename.is_empty()) { cd->files.insert(filename); @@ -126,7 +125,7 @@ PackedData::~PackedData() { ////////////////////////////////////////////////////////////////// -bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset) { +bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { return false; @@ -261,7 +260,7 @@ bool FileAccessPack::is_open() const { return f->is_open(); } -void FileAccessPack::seek(size_t p_position) { +void FileAccessPack::seek(uint64_t p_position) { if (p_position > pf.size) { eof = true; } else { @@ -276,11 +275,11 @@ void FileAccessPack::seek_end(int64_t p_position) { seek(pf.size + p_position); } -size_t FileAccessPack::get_position() const { +uint64_t FileAccessPack::get_position() const { return pos; } -size_t FileAccessPack::get_len() const { +uint64_t FileAccessPack::get_length() const { return pf.size; } @@ -298,18 +297,17 @@ uint8_t FileAccessPack::get_8() const { return f->get_8(); } -int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessPack::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); if (eof) { return 0; } - uint64_t to_read = p_length; + int64_t to_read = p_length; if (to_read + pos > pf.size) { eof = true; - to_read = int64_t(pf.size) - int64_t(pos); + to_read = (int64_t)pf.size - (int64_t)pos; } pos += p_length; @@ -322,9 +320,9 @@ int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const { return to_read; } -void FileAccessPack::set_endian_swap(bool p_swap) { - FileAccess::set_endian_swap(p_swap); - f->set_endian_swap(p_swap); +void FileAccessPack::set_big_endian(bool p_big_endian) { + FileAccess::set_big_endian(p_big_endian); + f->set_big_endian(p_big_endian); } Error FileAccessPack::get_error() const { @@ -342,7 +340,7 @@ void FileAccessPack::store_8(uint8_t p_dest) { ERR_FAIL(); } -void FileAccessPack::store_buffer(const uint8_t *p_src, int p_length) { +void FileAccessPack::store_buffer(const uint8_t *p_src, uint64_t p_length) { ERR_FAIL(); } @@ -549,7 +547,7 @@ Error DirAccessPack::remove(String p_name) { return ERR_UNAVAILABLE; } -size_t DirAccessPack::get_space_left() { +uint64_t DirAccessPack::get_space_left() { return 0; } diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 343adbe592..7a83fc938f 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -36,6 +36,7 @@ #include "core/string/print_string.h" #include "core/templates/list.h" #include "core/templates/map.h" +#include "core/templates/set.h" // Godot's packed file magic header ("GDPC" in ASCII). #define PACK_HEADER_MAGIC 0x43504447 @@ -111,13 +112,13 @@ private: public: void add_pack_source(PackSource *p_source); - void add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted = false); // for PackSource + void add_path(const String &p_pkg_path, const String &p_path, uint64_t p_ofs, uint64_t p_size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted = false); // for PackSource void set_disabled(bool p_disabled) { disabled = p_disabled; } _FORCE_INLINE_ bool is_disabled() const { return disabled; } static PackedData *get_singleton() { return singleton; } - Error add_pack(const String &p_path, bool p_replace_files, size_t p_offset); + Error add_pack(const String &p_path, bool p_replace_files, uint64_t p_offset); _FORCE_INLINE_ FileAccess *try_open_path(const String &p_path); _FORCE_INLINE_ bool has_path(const String &p_path); @@ -131,21 +132,21 @@ public: class PackSource { public: - virtual bool try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset) = 0; + virtual bool try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) = 0; virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0; virtual ~PackSource() {} }; class PackedSourcePCK : public PackSource { public: - virtual bool try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset); + virtual bool try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset); virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file); }; class FileAccessPack : public FileAccess { PackedData::PackedFile pf; - mutable size_t pos; + mutable uint64_t pos; mutable bool eof; uint64_t off; @@ -159,25 +160,25 @@ public: virtual void close(); virtual bool is_open() const; - virtual void seek(size_t p_position); + virtual void seek(uint64_t p_position); virtual void seek_end(int64_t p_position = 0); - virtual size_t get_position() const; - virtual size_t get_len() const; + virtual uint64_t get_position() const; + virtual uint64_t get_length() const; virtual bool eof_reached() const; virtual uint8_t get_8() const; - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; - virtual void set_endian_swap(bool p_swap); + virtual void set_big_endian(bool p_big_endian); virtual Error get_error() const; virtual void flush(); virtual void store_8(uint8_t p_dest); - virtual void store_buffer(const uint8_t *p_src, int p_length); + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); virtual bool file_exists(const String &p_name); @@ -242,7 +243,11 @@ public: virtual Error rename(String p_from, String p_to); virtual Error remove(String p_name); - size_t get_space_left(); + uint64_t get_space_left(); + + virtual bool is_link(String p_file) { return false; } + virtual String read_link(String p_file) { return p_file; } + virtual Error create_link(String p_source, String p_target) { return FAILED; } virtual String get_filesystem_type() const; diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index 586c988974..b8383fd865 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -32,7 +32,6 @@ #include "file_access_zip.h" -#include "core/os/copymem.h" #include "core/os/file_access.h" ZipArchive *ZipArchive::instance = nullptr; @@ -44,14 +43,14 @@ static void *godot_open(void *data, const char *p_fname, int mode) { return nullptr; } - FileAccess *f = (FileAccess *)data; - f->open(p_fname, FileAccess::READ); + FileAccess *f = FileAccess::open(p_fname, FileAccess::READ); + ERR_FAIL_COND_V(!f, nullptr); - return f->is_open() ? data : nullptr; + return f; } static uLong godot_read(void *data, void *fdata, void *buf, uLong size) { - FileAccess *f = (FileAccess *)data; + FileAccess *f = (FileAccess *)fdata; f->get_buffer((uint8_t *)buf, size); return size; } @@ -61,20 +60,20 @@ static uLong godot_write(voidpf opaque, voidpf stream, const void *buf, uLong si } static long godot_tell(voidpf opaque, voidpf stream) { - FileAccess *f = (FileAccess *)opaque; + FileAccess *f = (FileAccess *)stream; return f->get_position(); } static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) { - FileAccess *f = (FileAccess *)opaque; + FileAccess *f = (FileAccess *)stream; - int pos = offset; + uint64_t 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; + pos = f->get_length() + offset; break; default: break; @@ -85,13 +84,17 @@ static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) { } static int godot_close(voidpf opaque, voidpf stream) { - FileAccess *f = (FileAccess *)opaque; - f->close(); + FileAccess *f = (FileAccess *)stream; + if (f) { + f->close(); + memdelete(f); + f = nullptr; + } return 0; } static int godot_testerror(voidpf opaque, voidpf stream) { - FileAccess *f = (FileAccess *)opaque; + FileAccess *f = (FileAccess *)stream; return f->get_error() != OK ? 1 : 0; } @@ -106,23 +109,18 @@ static void godot_free(voidpf opaque, voidpf address) { void ZipArchive::close_handle(unzFile p_file) const { ERR_FAIL_COND_MSG(!p_file, "Cannot close a file if none is open."); - FileAccess *f = (FileAccess *)unzGetOpaque(p_file); unzCloseCurrentFile(p_file); unzClose(p_file); - memdelete(f); } unzFile ZipArchive::get_file_handle(String p_file) const { ERR_FAIL_COND_V_MSG(!file_exists(p_file), nullptr, "File '" + p_file + " doesn't exist."); File file = files[p_file]; - FileAccess *f = FileAccess::open(packages[file.package].filename, FileAccess::READ); - ERR_FAIL_COND_V_MSG(!f, nullptr, "Cannot open file '" + packages[file.package].filename + "'."); - zlib_filefunc_def io; - zeromem(&io, sizeof(io)); + memset(&io, 0, sizeof(io)); - io.opaque = f; + io.opaque = nullptr; io.zopen_file = godot_open; io.zread_file = godot_read; io.zwrite_file = godot_write; @@ -136,7 +134,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const { io.free_mem = godot_free; unzFile pkg = unzOpen2(packages[file.package].filename.utf8().get_data(), &io); - ERR_FAIL_COND_V(!pkg, nullptr); + ERR_FAIL_COND_V_MSG(!pkg, nullptr, "Cannot open file '" + packages[file.package].filename + "'."); int unz_err = unzGoToFilePos(pkg, &file.file_pos); if (unz_err != UNZ_OK || unzOpenCurrentFile(pkg) != UNZ_OK) { unzClose(pkg); @@ -146,8 +144,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const { return pkg; } -bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset = 0) { - //printf("opening zip pack %s, %i, %i\n", p_name.utf8().get_data(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz")); +bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset = 0) { // load with offset feature only supported for PCK files ERR_FAIL_COND_V_MSG(p_offset != 0, false, "Invalid PCK data. Note that loading files with a non-zero offset isn't supported with ZIP archives."); @@ -156,12 +153,9 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, size_ } zlib_filefunc_def io; + memset(&io, 0, sizeof(io)); - FileAccess *fa = FileAccess::open(p_path, FileAccess::READ); - if (!fa) { - return false; - } - io.opaque = fa; + io.opaque = nullptr; io.zopen_file = godot_open; io.zread_file = godot_read; io.zwrite_file = godot_write; @@ -232,9 +226,7 @@ ZipArchive::ZipArchive() { ZipArchive::~ZipArchive() { for (int i = 0; i < packages.size(); i++) { - FileAccess *f = (FileAccess *)unzGetOpaque(packages[i].zfile); unzClose(packages[i].zfile); - memdelete(f); } packages.clear(); @@ -270,22 +262,23 @@ bool FileAccessZip::is_open() const { return zfile != nullptr; } -void FileAccessZip::seek(size_t p_position) { +void FileAccessZip::seek(uint64_t p_position) { ERR_FAIL_COND(!zfile); + unzSeekCurrentFile(zfile, p_position); } void FileAccessZip::seek_end(int64_t p_position) { ERR_FAIL_COND(!zfile); - unzSeekCurrentFile(zfile, get_len() + p_position); + unzSeekCurrentFile(zfile, get_length() + p_position); } -size_t FileAccessZip::get_position() const { +uint64_t FileAccessZip::get_position() const { ERR_FAIL_COND_V(!zfile, 0); return unztell(zfile); } -size_t FileAccessZip::get_len() const { +uint64_t FileAccessZip::get_length() const { ERR_FAIL_COND_V(!zfile, 0); return file_info.uncompressed_size; } @@ -302,17 +295,17 @@ uint8_t FileAccessZip::get_8() const { return ret; } -int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessZip::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V(!zfile, -1); + at_eof = unzeof(zfile); if (at_eof) { return 0; } - int read = unzReadCurrentFile(zfile, p_dst, p_length); + int64_t read = unzReadCurrentFile(zfile, p_dst, p_length); ERR_FAIL_COND_V(read < 0, read); - if (read < p_length) { + if ((uint64_t)read < p_length) { at_eof = true; } return read; diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index 8559f871ce..cca14ded62 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -67,7 +67,7 @@ public: bool file_exists(String p_name) const; - virtual bool try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset); + virtual bool try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset); FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file); static ZipArchive *get_singleton(); @@ -87,20 +87,21 @@ public: virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; virtual Error get_error() const; ///< get last error virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte + virtual bool file_exists(const String &p_name); ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) { return 0; } // todo diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 3863dce0f6..0cf870e7e7 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -77,7 +77,7 @@ Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl, if (conn_host.is_valid_ip_address()) { // Host contains valid IP - Error err = tcp_connection->connect_to_host(IP_Address(conn_host), p_port); + Error err = tcp_connection->connect_to_host(IPAddress(conn_host), p_port); if (err) { status = STATUS_CANT_CONNECT; return err; @@ -328,7 +328,7 @@ Error HTTPClient::poll() { return OK; // Still resolving case IP::RESOLVER_STATUS_DONE: { - IP_Address host = IP::get_singleton()->get_resolve_item_address(resolving); + IPAddress host = IP::get_singleton()->get_resolve_item_address(resolving); Error err = tcp_connection->connect_to_host(host, conn_port); IP::get_singleton()->erase_resolve_item(resolving); resolving = IP::RESOLVER_INVALID_ID; @@ -633,7 +633,7 @@ PackedByteArray HTTPClient::read_response_body_chunk() { ret.resize(chunk.size() - 2); uint8_t *w = ret.ptrw(); - copymem(w, chunk.ptr(), chunk.size() - 2); + memcpy(w, chunk.ptr(), chunk.size() - 2); chunk.clear(); } diff --git a/core/io/image.cpp b/core/io/image.cpp index 5d46d75efe..c36fa6e45f 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -34,7 +34,6 @@ #include "core/io/image_loader.h" #include "core/io/resource_loader.h" #include "core/math/math_funcs.h" -#include "core/os/copymem.h" #include "core/string/print_string.h" #include "core/templates/hash_map.h" @@ -1537,7 +1536,7 @@ void Image::shrink_x2() { uint8_t *w = new_img.ptrw(); const uint8_t *r = data.ptr(); - copymem(w, &r[ofs], new_size); + memcpy(w, &r[ofs], new_size); } width = MAX(width / 2, 1); @@ -1932,7 +1931,7 @@ Error Image::generate_mipmap_roughness(RoughnessChannel p_roughness_channel, con uint8_t* wr = imgdata.ptrw(); - copymem(wr.ptr(), ptr, size); + memcpy(wr.ptr(), ptr, size); wr = uint8_t*(); Ref<Image> im; im.instance(); @@ -1982,7 +1981,7 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma { uint8_t *w = data.ptrw(); - zeromem(w, size); + memset(w, 0, size); } width = p_width; @@ -3010,26 +3009,28 @@ Image::UsedChannels Image::detect_used_channels(CompressSource p_source) { ERR_FAIL_COND_V(is_compressed(), USED_CHANNELS_RGBA); bool r = false, g = false, b = false, a = false, c = false; - for (int i = 0; i < width; i++) { - for (int j = 0; j < height; j++) { - Color col = get_pixel(i, j); + const uint8_t *data_ptr = data.ptr(); - if (col.r > 0.001) { - r = true; - } - if (col.g > 0.001) { - g = true; - } - if (col.b > 0.001) { - b = true; - } - if (col.a < 0.999) { - a = true; - } + uint32_t data_total = width * height; - if (col.r != col.b || col.r != col.g || col.b != col.g) { - c = true; - } + for (uint32_t i = 0; i < data_total; i++) { + Color col = _get_color_at_ofs(data_ptr, i); + + if (col.r > 0.001) { + r = true; + } + if (col.g > 0.001) { + g = true; + } + if (col.b > 0.001) { + b = true; + } + if (col.a < 0.999) { + a = true; + } + + if (col.r != col.b || col.r != col.g || col.b != col.g) { + c = true; } } @@ -3293,7 +3294,7 @@ Ref<Image> Image::get_image_from_mipmap(int p_mipamp) const { { uint8_t *wr = new_data.ptrw(); const uint8_t *rd = data.ptr(); - copymem(wr, rd + ofs, size); + memcpy(wr, rd + ofs, size); } Ref<Image> image; @@ -3620,5 +3621,5 @@ Ref<Resource> Image::duplicate(bool p_subresources) const { } void Image::set_as_black() { - zeromem(data.ptrw(), data.size()); + memset(data.ptrw(), 0, data.size()); } diff --git a/core/io/ip.cpp b/core/io/ip.cpp index e1d9c19f10..001b1c4757 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -41,13 +41,15 @@ VARIANT_ENUM_CAST(IP::ResolverStatus); struct _IP_ResolverPrivate { struct QueueItem { SafeNumeric<IP::ResolverStatus> status; - IP_Address response; + + List<IPAddress> response; + String hostname; IP::Type type; void clear() { status.set(IP::RESOLVER_STATUS_NONE); - response = IP_Address(); + response.clear(); type = IP::TYPE_NONE; hostname = ""; }; @@ -80,13 +82,9 @@ struct _IP_ResolverPrivate { if (queue[i].status.get() != IP::RESOLVER_STATUS_WAITING) { continue; } - queue[i].response = IP::get_singleton()->resolve_hostname(queue[i].hostname, queue[i].type); - if (!queue[i].response.is_valid()) { - queue[i].status.set(IP::RESOLVER_STATUS_ERROR); - } else { - queue[i].status.set(IP::RESOLVER_STATUS_DONE); - } + IP::get_singleton()->_resolve_hostname(queue[i].response, queue[i].hostname, queue[i].type); + queue[i].status.set(queue[i].response.is_empty() ? IP::RESOLVER_STATUS_ERROR : IP::RESOLVER_STATUS_DONE); } } @@ -101,25 +99,51 @@ struct _IP_ResolverPrivate { } } - HashMap<String, IP_Address> cache; + HashMap<String, List<IPAddress>> cache; static String get_cache_key(String p_hostname, IP::Type p_type) { return itos(p_type) + p_hostname; } }; -IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) { +IPAddress IP::resolve_hostname(const String &p_hostname, IP::Type p_type) { MutexLock lock(resolver->mutex); + List<IPAddress> res; + String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type); - if (resolver->cache.has(key) && resolver->cache[key].is_valid()) { - IP_Address res = resolver->cache[key]; - return res; + if (resolver->cache.has(key)) { + res = resolver->cache[key]; + } else { + _resolve_hostname(res, p_hostname, p_type); + resolver->cache[key] = res; } - IP_Address res = _resolve_hostname(p_hostname, p_type); - resolver->cache[key] = res; - return res; + for (int i = 0; i < res.size(); ++i) { + if (res[i].is_valid()) { + return res[i]; + } + } + return IPAddress(); +} + +Array IP::resolve_hostname_addresses(const String &p_hostname, Type p_type) { + MutexLock lock(resolver->mutex); + + String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type); + if (!resolver->cache.has(key)) { + _resolve_hostname(resolver->cache[key], p_hostname, p_type); + } + + List<IPAddress> res = resolver->cache[key]; + + Array result; + for (int i = 0; i < res.size(); ++i) { + if (res[i].is_valid()) { + result.push_back(String(res[i])); + } + } + return result; } IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Type p_type) { @@ -135,11 +159,11 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type); resolver->queue[id].hostname = p_hostname; resolver->queue[id].type = p_type; - if (resolver->cache.has(key) && resolver->cache[key].is_valid()) { + if (resolver->cache.has(key)) { resolver->queue[id].response = resolver->cache[key]; resolver->queue[id].status.set(IP::RESOLVER_STATUS_DONE); } else { - resolver->queue[id].response = IP_Address(); + resolver->queue[id].response = List<IPAddress>(); resolver->queue[id].status.set(IP::RESOLVER_STATUS_WAITING); if (resolver->thread.is_started()) { resolver->sem.post(); @@ -158,24 +182,49 @@ IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const { if (resolver->queue[p_id].status.get() == IP::RESOLVER_STATUS_NONE) { ERR_PRINT("Condition status == IP::RESOLVER_STATUS_NONE"); - resolver->mutex.unlock(); return IP::RESOLVER_STATUS_NONE; } return resolver->queue[p_id].status.get(); } -IP_Address IP::get_resolve_item_address(ResolverID p_id) const { - ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP_Address()); +IPAddress IP::get_resolve_item_address(ResolverID p_id) const { + ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IPAddress()); MutexLock lock(resolver->mutex); if (resolver->queue[p_id].status.get() != IP::RESOLVER_STATUS_DONE) { ERR_PRINT("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet."); - resolver->mutex.unlock(); - return IP_Address(); + return IPAddress(); + } + + List<IPAddress> res = resolver->queue[p_id].response; + + for (int i = 0; i < res.size(); ++i) { + if (res[i].is_valid()) { + return res[i]; + } } + return IPAddress(); +} + +Array IP::get_resolve_item_addresses(ResolverID p_id) const { + ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, Array()); + MutexLock lock(resolver->mutex); - return resolver->queue[p_id].response; + if (resolver->queue[p_id].status.get() != IP::RESOLVER_STATUS_DONE) { + ERR_PRINT("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet."); + return Array(); + } + + List<IPAddress> res = resolver->queue[p_id].response; + + Array result; + for (int i = 0; i < res.size(); ++i) { + if (res[i].is_valid()) { + result.push_back(String(res[i])); + } + } + return result; } void IP::erase_resolve_item(ResolverID p_id) { @@ -201,9 +250,9 @@ void IP::clear_cache(const String &p_hostname) { Array IP::_get_local_addresses() const { Array addresses; - List<IP_Address> ip_addresses; + List<IPAddress> ip_addresses; get_local_addresses(&ip_addresses); - for (List<IP_Address>::Element *E = ip_addresses.front(); E; E = E->next()) { + for (List<IPAddress>::Element *E = ip_addresses.front(); E; E = E->next()) { addresses.push_back(E->get()); } @@ -222,7 +271,7 @@ Array IP::_get_local_interfaces() const { rc["index"] = c.index; Array ips; - for (const List<IP_Address>::Element *F = c.ip_addresses.front(); F; F = F->next()) { + for (const List<IPAddress>::Element *F = c.ip_addresses.front(); F; F = F->next()) { ips.push_front(F->get()); } rc["addresses"] = ips; @@ -233,11 +282,11 @@ Array IP::_get_local_interfaces() const { return results; } -void IP::get_local_addresses(List<IP_Address> *r_addresses) const { +void IP::get_local_addresses(List<IPAddress> *r_addresses) const { Map<String, Interface_Info> interfaces; get_local_interfaces(&interfaces); for (Map<String, Interface_Info>::Element *E = interfaces.front(); E; E = E->next()) { - for (const List<IP_Address>::Element *F = E->get().ip_addresses.front(); F; F = F->next()) { + for (const List<IPAddress>::Element *F = E->get().ip_addresses.front(); F; F = F->next()) { r_addresses->push_front(F->get()); } } @@ -245,9 +294,11 @@ void IP::get_local_addresses(List<IP_Address> *r_addresses) const { void IP::_bind_methods() { ClassDB::bind_method(D_METHOD("resolve_hostname", "host", "ip_type"), &IP::resolve_hostname, DEFVAL(IP::TYPE_ANY)); + ClassDB::bind_method(D_METHOD("resolve_hostname_addresses", "host", "ip_type"), &IP::resolve_hostname_addresses, DEFVAL(IP::TYPE_ANY)); ClassDB::bind_method(D_METHOD("resolve_hostname_queue_item", "host", "ip_type"), &IP::resolve_hostname_queue_item, DEFVAL(IP::TYPE_ANY)); ClassDB::bind_method(D_METHOD("get_resolve_item_status", "id"), &IP::get_resolve_item_status); ClassDB::bind_method(D_METHOD("get_resolve_item_address", "id"), &IP::get_resolve_item_address); + ClassDB::bind_method(D_METHOD("get_resolve_item_addresses", "id"), &IP::get_resolve_item_addresses); ClassDB::bind_method(D_METHOD("erase_resolve_item", "id"), &IP::erase_resolve_item); ClassDB::bind_method(D_METHOD("get_local_addresses"), &IP::_get_local_addresses); ClassDB::bind_method(D_METHOD("get_local_interfaces"), &IP::_get_local_interfaces); diff --git a/core/io/ip.h b/core/io/ip.h index ae080b8e26..3c6040a1f0 100644 --- a/core/io/ip.h +++ b/core/io/ip.h @@ -69,7 +69,6 @@ protected: static IP *singleton; static void _bind_methods(); - virtual IP_Address _resolve_hostname(const String &p_hostname, Type p_type = TYPE_ANY) = 0; Array _get_local_addresses() const; Array _get_local_interfaces() const; @@ -80,15 +79,20 @@ public: String name; String name_friendly; String index; - List<IP_Address> ip_addresses; + List<IPAddress> ip_addresses; }; - IP_Address resolve_hostname(const String &p_hostname, Type p_type = TYPE_ANY); + IPAddress resolve_hostname(const String &p_hostname, Type p_type = TYPE_ANY); + Array resolve_hostname_addresses(const String &p_hostname, Type p_type = TYPE_ANY); // async resolver hostname ResolverID resolve_hostname_queue_item(const String &p_hostname, Type p_type = TYPE_ANY); ResolverStatus get_resolve_item_status(ResolverID p_id) const; - IP_Address get_resolve_item_address(ResolverID p_id) const; - virtual void get_local_addresses(List<IP_Address> *r_addresses) const; + IPAddress get_resolve_item_address(ResolverID p_id) const; + virtual void get_local_addresses(List<IPAddress> *r_addresses) const; + + virtual void _resolve_hostname(List<IPAddress> &r_addresses, const String &p_hostname, Type p_type = TYPE_ANY) const = 0; + Array get_resolve_item_addresses(ResolverID p_id) const; + virtual void get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const = 0; void erase_resolve_item(ResolverID p_id); diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp index 5f98eb69e8..1c1ac8a88f 100644 --- a/core/io/ip_address.cpp +++ b/core/io/ip_address.cpp @@ -30,14 +30,14 @@ #include "ip_address.h" /* -IP_Address::operator Variant() const { +IPAddress::operator Variant() const { return operator String(); }*/ #include <stdio.h> #include <string.h> -IP_Address::operator String() const { +IPAddress::operator String() const { if (wildcard) { return "*"; } @@ -90,7 +90,7 @@ static void _parse_hex(const String &p_string, int p_start, uint8_t *p_dst) { p_dst[1] = ret & 0xff; } -void IP_Address::_parse_ipv6(const String &p_string) { +void IPAddress::_parse_ipv6(const String &p_string) { static const int parts_total = 8; int parts[parts_total] = { 0 }; int parts_count = 0; @@ -146,7 +146,7 @@ void IP_Address::_parse_ipv6(const String &p_string) { } } -void IP_Address::_parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret) { +void IPAddress::_parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret) { String ip; if (p_start != 0) { ip = p_string.substr(p_start, p_string.length() - p_start); @@ -161,33 +161,33 @@ void IP_Address::_parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret } } -void IP_Address::clear() { +void IPAddress::clear() { memset(&field8[0], 0, sizeof(field8)); valid = false; wildcard = false; } -bool IP_Address::is_ipv4() const { +bool IPAddress::is_ipv4() const { return (field32[0] == 0 && field32[1] == 0 && field16[4] == 0 && field16[5] == 0xffff); } -const uint8_t *IP_Address::get_ipv4() const { +const uint8_t *IPAddress::get_ipv4() const { ERR_FAIL_COND_V_MSG(!is_ipv4(), &(field8[12]), "IPv4 requested, but current IP is IPv6."); // Not the correct IPv4 (it's an IPv6), but we don't want to return a null pointer risking an engine crash. return &(field8[12]); } -void IP_Address::set_ipv4(const uint8_t *p_ip) { +void IPAddress::set_ipv4(const uint8_t *p_ip) { clear(); valid = true; field16[5] = 0xffff; field32[3] = *((const uint32_t *)p_ip); } -const uint8_t *IP_Address::get_ipv6() const { +const uint8_t *IPAddress::get_ipv6() const { return field8; } -void IP_Address::set_ipv6(const uint8_t *p_buf) { +void IPAddress::set_ipv6(const uint8_t *p_buf) { clear(); valid = true; for (int i = 0; i < 16; i++) { @@ -195,7 +195,7 @@ void IP_Address::set_ipv6(const uint8_t *p_buf) { } } -IP_Address::IP_Address(const String &p_string) { +IPAddress::IPAddress(const String &p_string) { clear(); if (p_string == "*") { @@ -225,7 +225,7 @@ _FORCE_INLINE_ static void _32_to_buf(uint8_t *p_dst, uint32_t p_n) { p_dst[3] = (p_n >> 0) & 0xff; } -IP_Address::IP_Address(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, bool is_v6) { +IPAddress::IPAddress(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, bool is_v6) { clear(); valid = true; if (!is_v6) { diff --git a/core/io/ip_address.h b/core/io/ip_address.h index 49bf83d72f..05da675704 100644 --- a/core/io/ip_address.h +++ b/core/io/ip_address.h @@ -33,7 +33,7 @@ #include "core/string/ustring.h" -struct IP_Address { +struct IPAddress { private: union { uint8_t field8[16]; @@ -50,7 +50,7 @@ protected: public: //operator Variant() const; - bool operator==(const IP_Address &p_ip) const { + bool operator==(const IPAddress &p_ip) const { if (p_ip.valid != valid) { return false; } @@ -65,7 +65,7 @@ public: return true; } - bool operator!=(const IP_Address &p_ip) const { + bool operator!=(const IPAddress &p_ip) const { if (p_ip.valid != valid) { return true; } @@ -91,9 +91,9 @@ public: void set_ipv6(const uint8_t *p_buf); operator String() const; - IP_Address(const String &p_string); - IP_Address(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, bool is_v6 = false); - IP_Address() { clear(); } + IPAddress(const String &p_string); + IPAddress(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, bool is_v6 = false); + IPAddress() { clear(); } }; #endif // IP_ADDRESS_H diff --git a/core/io/json.cpp b/core/io/json.cpp index 0d9117fdda..394cf216e8 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -347,7 +347,6 @@ Error JSON::_parse_value(Variant &value, Token &token, const char32_t *p_str, in return err; } value = d; - return OK; } else if (token.type == TK_BRACKET_OPEN) { Array a; Error err = _parse_array(a, p_str, index, p_len, line, r_err_str); @@ -355,8 +354,6 @@ Error JSON::_parse_value(Variant &value, Token &token, const char32_t *p_str, in return err; } value = a; - return OK; - } else if (token.type == TK_IDENTIFIER) { String id = token.value; if (id == "true") { @@ -369,18 +366,16 @@ Error JSON::_parse_value(Variant &value, Token &token, const char32_t *p_str, in r_err_str = "Expected 'true','false' or 'null', got '" + id + "'."; return ERR_PARSE_ERROR; } - return OK; - } else if (token.type == TK_NUMBER) { value = token.value; - return OK; } else if (token.type == TK_STRING) { value = token.value; - return OK; } else { r_err_str = "Expected value, got " + String(tk_name[token.type]) + "."; return ERR_PARSE_ERROR; } + + return OK; } Error JSON::_parse_array(Array &array, const char32_t *p_str, int &index, int p_len, int &line, String &r_err_str) { @@ -499,6 +494,19 @@ Error JSON::parse(const String &p_json, Variant &r_ret, String &r_err_str, int & err = _parse_value(r_ret, token, str, idx, len, r_err_line, r_err_str); + // Check if EOF is reached + // or it's a type of the next token. + if (err == OK && idx < len) { + err = _get_token(str, idx, len, token, r_err_line, r_err_str); + + if (err || token.type != TK_EOF) { + r_err_str = "Expected 'EOF'"; + // Reset return value to empty `Variant` + r_ret = Variant(); + return ERR_PARSE_ERROR; + } + } + return err; } diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 218a612da2..18e1092c26 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -279,9 +279,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } } break; - case Variant::QUAT: { + case Variant::QUATERNION: { ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA); - Quat val; + Quaternion val; val.x = decode_float(&buf[0]); val.y = decode_float(&buf[4]); val.z = decode_float(&buf[8]); @@ -325,9 +325,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } } break; - case Variant::TRANSFORM: { + case Variant::TRANSFORM3D: { ERR_FAIL_COND_V(len < 4 * 12, ERR_INVALID_DATA); - Transform val; + Transform3D val; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { val.basis.elements[i][j] = decode_float(&buf[(i * 3 + j) * 4]); @@ -851,7 +851,7 @@ static void _encode_string(const String &p_string, uint8_t *&buf, int &r_len) { if (buf) { encode_uint32(utf8.length(), buf); buf += 4; - copymem(buf, utf8.get_data(), utf8.length()); + memcpy(buf, utf8.get_data(), utf8.length()); buf += utf8.length(); } @@ -889,7 +889,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo // Test for potential wrong values sent by the debugger when it breaks. Object *obj = p_variant.get_validated_object(); if (!obj) { - // Object is invalid, send a nullptr instead. + // Object is invalid, send a nullptr instead. if (buf) { encode_uint32(Variant::NIL, buf); } @@ -995,7 +995,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo if (buf) { encode_uint32(utf8.length(), buf); buf += 4; - copymem(buf, utf8.get_data(), utf8.length()); + memcpy(buf, utf8.get_data(), utf8.length()); buf += pad + utf8.length(); } @@ -1079,7 +1079,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo Transform2D val = p_variant; for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { - copymem(&buf[(i * 2 + j) * 4], &val.elements[i][j], sizeof(float)); + memcpy(&buf[(i * 2 + j) * 4], &val.elements[i][j], sizeof(float)); } } } @@ -1099,9 +1099,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 4 * 4; } break; - case Variant::QUAT: { + case Variant::QUATERNION: { if (buf) { - Quat q = p_variant; + Quaternion q = p_variant; encode_float(q.x, &buf[0]); encode_float(q.y, &buf[4]); encode_float(q.z, &buf[8]); @@ -1130,7 +1130,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo Basis val = p_variant; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { - copymem(&buf[(i * 3 + j) * 4], &val.elements[i][j], sizeof(float)); + memcpy(&buf[(i * 3 + j) * 4], &val.elements[i][j], sizeof(float)); } } } @@ -1138,12 +1138,12 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 9 * 4; } break; - case Variant::TRANSFORM: { + case Variant::TRANSFORM3D: { if (buf) { - Transform val = p_variant; + Transform3D val = p_variant; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { - copymem(&buf[(i * 3 + j) * 4], &val.basis.elements[i][j], sizeof(float)); + memcpy(&buf[(i * 3 + j) * 4], &val.basis.elements[i][j], sizeof(float)); } } @@ -1258,7 +1258,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo if (buf) { encode_uint32(utf8.length()+1,buf); buf+=4; - copymem(buf,utf8.get_data(),utf8.length()+1); + memcpy(buf,utf8.get_data(),utf8.length()+1); } r_len+=4+utf8.length()+1; @@ -1314,7 +1314,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo encode_uint32(datalen, buf); buf += 4; const uint8_t *r = data.ptr(); - copymem(buf, &r[0], datalen * datasize); + memcpy(buf, &r[0], datalen * datasize); buf += datalen * datasize; } @@ -1412,7 +1412,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo if (buf) { encode_uint32(utf8.length() + 1, buf); buf += 4; - copymem(buf, utf8.get_data(), utf8.length() + 1); + memcpy(buf, utf8.get_data(), utf8.length() + 1); buf += utf8.length() + 1; } diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 94060cfe0b..78ec7ea21a 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -44,6 +44,56 @@ #include "core/os/os.h" #endif +String _get_rpc_md5(const Node *p_node) { + String rpc_list; + const Vector<MultiplayerAPI::RPCConfig> node_config = p_node->get_node_rpc_methods(); + for (int i = 0; i < node_config.size(); i++) { + rpc_list += String(node_config[i].name); + } + if (p_node->get_script_instance()) { + const Vector<MultiplayerAPI::RPCConfig> script_config = p_node->get_script_instance()->get_rpc_methods(); + for (int i = 0; i < script_config.size(); i++) { + rpc_list += String(script_config[i].name); + } + } + return rpc_list.md5_text(); +} + +const MultiplayerAPI::RPCConfig _get_rpc_config(const Node *p_node, const StringName &p_method, uint16_t &r_id) { + const Vector<MultiplayerAPI::RPCConfig> node_config = p_node->get_node_rpc_methods(); + for (int i = 0; i < node_config.size(); i++) { + if (node_config[i].name == p_method) { + r_id = ((uint16_t)i) & (1 << 15); + return node_config[i]; + } + } + if (p_node->get_script_instance()) { + const Vector<MultiplayerAPI::RPCConfig> script_config = p_node->get_script_instance()->get_rpc_methods(); + for (int i = 0; i < script_config.size(); i++) { + if (script_config[i].name == p_method) { + r_id = (uint16_t)i; + return script_config[i]; + } + } + } + return MultiplayerAPI::RPCConfig(); +} + +const MultiplayerAPI::RPCConfig _get_rpc_config_by_id(Node *p_node, uint16_t p_id) { + Vector<MultiplayerAPI::RPCConfig> config; + uint16_t id = p_id; + if (id & (1 << 15)) { + id = id & ~(1 << 15); + config = p_node->get_node_rpc_methods(); + } else { + config = p_node->get_script_instance()->get_rpc_methods(); + } + if (id < config.size()) { + return config[p_id]; + } + return MultiplayerAPI::RPCConfig(); +} + _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_master, bool &r_skip_rpc) { switch (mode) { case MultiplayerAPI::RPC_MODE_DISABLED: { @@ -231,8 +281,7 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_ _process_confirm_path(p_from, p_packet, p_packet_len); } break; - case NETWORK_COMMAND_REMOTE_CALL: - case NETWORK_COMMAND_REMOTE_SET: { + case NETWORK_COMMAND_REMOTE_CALL: { // Extract packet meta int packet_min_size = 1; int name_id_offset = 1; @@ -302,13 +351,7 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_ } const int packet_len = get_packet_len(node_target, p_packet_len); - if (packet_type == NETWORK_COMMAND_REMOTE_CALL) { - _process_rpc(node, name_id, p_from, p_packet, packet_len, packet_min_size); - - } else { - _process_rset(node, name_id, p_from, p_packet, packet_len, packet_min_size); - } - + _process_rpc(node, name_id, p_from, p_packet, packet_len, packet_min_size); } break; case NETWORK_COMMAND_RAW: { @@ -362,16 +405,11 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id, ERR_FAIL_COND_MSG(p_offset > p_packet_len, "Invalid packet received. Size too small."); // Check that remote can call the RPC on this node. - StringName name = p_node->get_node_rpc_method(p_rpc_method_id); - RPCMode rpc_mode = p_node->get_node_rpc_mode_by_id(p_rpc_method_id); - if (name == StringName() && p_node->get_script_instance()) { - name = p_node->get_script_instance()->get_rpc_method(p_rpc_method_id); - rpc_mode = p_node->get_script_instance()->get_rpc_mode_by_id(p_rpc_method_id); - } - ERR_FAIL_COND(name == StringName()); + const RPCConfig config = _get_rpc_config_by_id(p_node, p_rpc_method_id); + ERR_FAIL_COND(config.name == StringName()); - bool can_call = _can_call_mode(p_node, rpc_mode, p_from); - ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + "."); + bool can_call = _can_call_mode(p_node, config.rpc_mode, p_from); + ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(config.name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)config.rpc_mode) + ", master is " + itos(p_node->get_network_master()) + "."); int argc = 0; bool byte_only = false; @@ -424,47 +462,14 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id, Callable::CallError ce; - p_node->call(name, (const Variant **)argp.ptr(), argc, ce); + p_node->call(config.name, (const Variant **)argp.ptr(), argc, ce); if (ce.error != Callable::CallError::CALL_OK) { - String error = Variant::get_call_error_text(p_node, name, (const Variant **)argp.ptr(), argc, ce); + String error = Variant::get_call_error_text(p_node, config.name, (const Variant **)argp.ptr(), argc, ce); error = "RPC - " + error; ERR_PRINT(error); } } -void MultiplayerAPI::_process_rset(Node *p_node, const uint16_t p_rpc_property_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) { - ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small."); - - // Check that remote can call the RSET on this node. - StringName name = p_node->get_node_rset_property(p_rpc_property_id); - RPCMode rset_mode = p_node->get_node_rset_mode_by_id(p_rpc_property_id); - if (name == StringName() && p_node->get_script_instance()) { - name = p_node->get_script_instance()->get_rset_property(p_rpc_property_id); - rset_mode = p_node->get_script_instance()->get_rset_mode_by_id(p_rpc_property_id); - } - ERR_FAIL_COND(name == StringName()); - - bool can_call = _can_call_mode(p_node, rset_mode, p_from); - ERR_FAIL_COND_MSG(!can_call, "RSET '" + String(name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + "."); - -#ifdef DEBUG_ENABLED - _profile_node_data("in_rset", p_node->get_instance_id()); -#endif - - Variant value; - Error err = _decode_and_decompress_variant(value, &p_packet[p_offset], p_packet_len - p_offset, nullptr); - - ERR_FAIL_COND_MSG(err != OK, "Invalid packet received. Unable to decode RSET value."); - - bool valid; - - p_node->set(name, value, &valid); - if (!valid) { - String error = "Error setting remote property '" + String(name) + "', not found in object of type " + p_node->get_class() + "."; - ERR_PRINT(error); - } -} - void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len) { ERR_FAIL_COND_MSG(p_packet_len < 38, "Invalid packet received. Size too small."); int ofs = 1; @@ -487,7 +492,7 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet, Node *node = root_node->get_node(path); ERR_FAIL_COND(node == nullptr); - const bool valid_rpc_checksum = node->get_rpc_md5() == methods_md5; + const bool valid_rpc_checksum = _get_rpc_md5(node) == methods_md5; if (valid_rpc_checksum == false) { ERR_PRINT("The rpc node checksum failed. Make sure to have the same methods on both nodes. Node path: " + path); } @@ -569,7 +574,7 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC const int path_len = encode_cstring(path.get_data(), nullptr); // Extract MD5 from rpc methods list. - const String methods_md5 = p_node->get_rpc_md5(); + const String methods_md5 = _get_rpc_md5(p_node); const int methods_md5_len = 33; // 32 + 1 for the `0` that is added by the encoder. Vector<uint8_t> packet; @@ -752,7 +757,7 @@ Error MultiplayerAPI::_decode_and_decompress_variant(Variant &r_variant, const u return OK; } -void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount) { +void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount) { ERR_FAIL_COND_MSG(network_peer.is_null(), "Attempt to remote call/set when networking is not active in SceneTree."); ERR_FAIL_COND_MSG(network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_CONNECTING, "Attempt to remote call/set when networking is not connected yet in SceneTree."); @@ -797,7 +802,7 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p // - `NetworkNameIdCompression` in the next 1 bit. // - `byte_only_or_no_args` in the next 1 bit. // - So we still have the last bit free! - uint8_t command_type = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL; + uint8_t command_type = NETWORK_COMMAND_REMOTE_CALL; uint8_t node_id_compression = UINT8_MAX; uint8_t name_id_compression = UINT8_MAX; bool byte_only_or_no_args = false; @@ -837,81 +842,42 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p ofs += 4; } - if (p_set) { - // Take the rpc property ID - uint16_t property_id = p_from->get_node_rset_property_id(p_name); - if (property_id == UINT16_MAX && p_from->get_script_instance()) { - property_id = p_from->get_script_instance()->get_rset_property_id(p_name); - } - ERR_FAIL_COND_MSG(property_id == UINT16_MAX, "Unable to take the `property_id` for the property:" + p_name + ". this can happen only if this property is not marked as `remote`."); - - if (property_id <= UINT8_MAX) { - // The ID fits in 1 byte - name_id_compression = NETWORK_NAME_ID_COMPRESSION_8; - MAKE_ROOM(ofs + 1); - packet_cache.write[ofs] = static_cast<uint8_t>(property_id); - ofs += 1; - } else { - // The ID is larger, let's use 2 bytes - name_id_compression = NETWORK_NAME_ID_COMPRESSION_16; - MAKE_ROOM(ofs + 2); - encode_uint16(property_id, &(packet_cache.write[ofs])); - ofs += 2; - } - - // Set argument. - int len(0); - Error err = _encode_and_compress_variant(*p_arg[0], nullptr, len); - ERR_FAIL_COND_MSG(err != OK, "Unable to encode RSET value. THIS IS LIKELY A BUG IN THE ENGINE!"); - MAKE_ROOM(ofs + len); - _encode_and_compress_variant(*p_arg[0], &(packet_cache.write[ofs]), len); - ofs += len; - + // Encode method ID + if (p_rpc_id <= UINT8_MAX) { + // The ID fits in 1 byte + name_id_compression = NETWORK_NAME_ID_COMPRESSION_8; + MAKE_ROOM(ofs + 1); + packet_cache.write[ofs] = static_cast<uint8_t>(p_rpc_id); + ofs += 1; } else { - // Take the rpc method ID - uint16_t method_id = p_from->get_node_rpc_method_id(p_name); - if (method_id == UINT16_MAX && p_from->get_script_instance()) { - method_id = p_from->get_script_instance()->get_rpc_method_id(p_name); - } - ERR_FAIL_COND_MSG(method_id == UINT16_MAX, - vformat("Unable to take the `method_id` for the function \"%s\" at path: \"%s\". This happens when the method is not marked as `remote`.", p_name, p_from->get_path())); - - if (method_id <= UINT8_MAX) { - // The ID fits in 1 byte - name_id_compression = NETWORK_NAME_ID_COMPRESSION_8; - MAKE_ROOM(ofs + 1); - packet_cache.write[ofs] = static_cast<uint8_t>(method_id); - ofs += 1; - } else { - // The ID is larger, let's use 2 bytes - name_id_compression = NETWORK_NAME_ID_COMPRESSION_16; - MAKE_ROOM(ofs + 2); - encode_uint16(method_id, &(packet_cache.write[ofs])); - ofs += 2; - } + // The ID is larger, let's use 2 bytes + name_id_compression = NETWORK_NAME_ID_COMPRESSION_16; + MAKE_ROOM(ofs + 2); + encode_uint16(p_rpc_id, &(packet_cache.write[ofs])); + ofs += 2; + } - if (p_argcount == 0) { - byte_only_or_no_args = true; - } else if (p_argcount == 1 && p_arg[0]->get_type() == Variant::PACKED_BYTE_ARRAY) { - byte_only_or_no_args = true; - // Special optimization when only the byte vector is sent. - const Vector<uint8_t> data = *p_arg[0]; - MAKE_ROOM(ofs + data.size()); - copymem(&(packet_cache.write[ofs]), data.ptr(), sizeof(uint8_t) * data.size()); - ofs += data.size(); - } else { - // Arguments - MAKE_ROOM(ofs + 1); - packet_cache.write[ofs] = p_argcount; - ofs += 1; - for (int i = 0; i < p_argcount; i++) { - int len(0); - Error err = _encode_and_compress_variant(*p_arg[i], nullptr, len); - ERR_FAIL_COND_MSG(err != OK, "Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!"); - MAKE_ROOM(ofs + len); - _encode_and_compress_variant(*p_arg[i], &(packet_cache.write[ofs]), len); - ofs += len; - } + if (p_argcount == 0) { + byte_only_or_no_args = true; + } else if (p_argcount == 1 && p_arg[0]->get_type() == Variant::PACKED_BYTE_ARRAY) { + byte_only_or_no_args = true; + // Special optimization when only the byte vector is sent. + const Vector<uint8_t> data = *p_arg[0]; + MAKE_ROOM(ofs + data.size()); + memcpy(&(packet_cache.write[ofs]), data.ptr(), sizeof(uint8_t) * data.size()); + ofs += data.size(); + } else { + // Arguments + MAKE_ROOM(ofs + 1); + packet_cache.write[ofs] = p_argcount; + ofs += 1; + for (int i = 0; i < p_argcount; i++) { + int len(0); + Error err = _encode_and_compress_variant(*p_arg[i], nullptr, len); + ERR_FAIL_COND_MSG(err != OK, "Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!"); + MAKE_ROOM(ofs + len); + _encode_and_compress_variant(*p_arg[i], &(packet_cache.write[ofs]), len); + ofs += len; } } @@ -927,7 +893,7 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p #endif // 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); + network_peer->set_transfer_mode(p_config.transfer_mode); if (has_all_peers) { // They all have verified paths, so send fast. @@ -1015,19 +981,15 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const bool call_local_native = false; bool call_local_script = false; bool is_master = p_node->is_network_master(); - + uint16_t rpc_id = UINT16_MAX; + const RPCConfig config = _get_rpc_config(p_node, p_method, rpc_id); + ERR_FAIL_COND_MSG(config.name == StringName(), + vformat("Unable to get the RPC configuration for the function \"%s\" at path: \"%s\". This happens when the method is not marked for RPCs.", p_method, p_node->get_path())); 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. - - RPCMode rpc_mode = p_node->get_node_rpc_mode(p_method); - call_local_native = _should_call_local(rpc_mode, is_master, skip_rpc); - - if (call_local_native) { - // Done below. - } else if (p_node->get_script_instance()) { - // Attempt with script. - rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_method); - call_local_script = _should_call_local(rpc_mode, is_master, skip_rpc); + if (rpc_id & (1 << 15)) { + call_local_native = _should_call_local(config.rpc_mode, is_master, skip_rpc); + } else { + call_local_script = _should_call_local(config.rpc_mode, is_master, skip_rpc); } } @@ -1036,7 +998,7 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const _profile_node_data("out_rpc", p_node->get_instance_id()); #endif - _send_rpc(p_node, p_peer_id, p_unreliable, false, p_method, p_arg, p_argcount); + _send_rpc(p_node, p_peer_id, rpc_id, config, p_method, p_arg, p_argcount); } if (call_local_native) { @@ -1071,70 +1033,6 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const ERR_FAIL_COND_MSG(skip_rpc && !(call_local_native || call_local_script), "RPC '" + p_method + "' on yourself is not allowed by selected mode."); } -void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) { - ERR_FAIL_COND_MSG(!network_peer.is_valid(), "Trying to RSET while no network peer is active."); - ERR_FAIL_COND_MSG(!p_node->is_inside_tree(), "Trying to RSET on a node which is not inside SceneTree."); - ERR_FAIL_COND_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, "Trying to send an RSET via a network peer which is not connected."); - - int node_id = network_peer->get_unique_id(); - bool is_master = p_node->is_network_master(); - bool skip_rset = node_id == p_peer_id; - bool set_local = 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. - RPCMode rpc_mode = p_node->get_node_rset_mode(p_property); - set_local = _should_call_local(rpc_mode, is_master, skip_rset); - - if (set_local) { - bool valid; - int temp_id = rpc_sender_id; - - rpc_sender_id = get_network_unique_id(); - p_node->set(p_property, p_value, &valid); - rpc_sender_id = temp_id; - - if (!valid) { - String error = "rset() aborted in local set, property not found: - " + String(p_property) + "."; - ERR_PRINT(error); - return; - } - } else if (p_node->get_script_instance()) { - // Attempt with script. - rpc_mode = p_node->get_script_instance()->get_rset_mode(p_property); - - set_local = _should_call_local(rpc_mode, is_master, skip_rset); - - if (set_local) { - int temp_id = rpc_sender_id; - - rpc_sender_id = get_network_unique_id(); - bool valid = p_node->get_script_instance()->set(p_property, p_value); - rpc_sender_id = temp_id; - - if (!valid) { - String error = "rset() aborted in local script set, property not found: - " + String(p_property) + "."; - ERR_PRINT(error); - return; - } - } - } - } - - if (skip_rset) { - ERR_FAIL_COND_MSG(!set_local, "RSET for '" + p_property + "' on yourself is not allowed by selected mode."); - return; - } - -#ifdef DEBUG_ENABLED - _profile_node_data("out_rset", p_node->get_instance_id()); -#endif - - const Variant *vptr = &p_value; - - _send_rpc(p_node, p_peer_id, p_unreliable, true, p_property, &vptr, 1); -} - Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, NetworkedMultiplayerPeer::TransferMode p_mode) { ERR_FAIL_COND_V_MSG(p_data.size() < 1, ERR_INVALID_DATA, "Trying to send an empty raw packet."); ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), ERR_UNCONFIGURED, "Trying to send a raw packet while no network peer is active."); diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h index 7f88b53a27..6a251cf77b 100644 --- a/core/io/multiplayer_api.h +++ b/core/io/multiplayer_api.h @@ -37,6 +37,35 @@ class MultiplayerAPI : public Reference { GDCLASS(MultiplayerAPI, Reference); +public: + enum RPCMode { + RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default) + RPC_MODE_REMOTE, // Using rpc() on it will call method in all remote peers + RPC_MODE_MASTER, // Using rpc() on it will call method on wherever the master is, be it local or remote + RPC_MODE_PUPPET, // Using rpc() on it will call method for all puppets + RPC_MODE_REMOTESYNC, // Using rpc() on it will call method in all remote peers and locally + RPC_MODE_MASTERSYNC, // Using rpc() on it will call method in the master peer and locally + RPC_MODE_PUPPETSYNC, // Using rpc() on it will call method in all puppets peers and locally + }; + + struct RPCConfig { + StringName name; + RPCMode rpc_mode = RPC_MODE_DISABLED; + NetworkedMultiplayerPeer::TransferMode transfer_mode = NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE; + int channel = 0; + + bool operator==(RPCConfig const &p_other) const { + return name == p_other.name; + } + }; + + struct SortRPCConfig { + StringName::AlphCompare compare; + bool operator()(const RPCConfig &p_a, const RPCConfig &p_b) const { + return compare(p_a.name, p_b.name); + } + }; + private: //path sent caches struct PathSentCache { @@ -72,10 +101,9 @@ protected: void _process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len); Node *_process_get_node(int p_from, const uint8_t *p_packet, uint32_t p_node_target, int p_packet_len); void _process_rpc(Node *p_node, const uint16_t p_rpc_method_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset); - void _process_rset(Node *p_node, const uint16_t p_rpc_property_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset); void _process_raw(int p_from, const uint8_t *p_packet, int p_packet_len); - void _send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount); + void _send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount); bool _send_confirm_path(Node *p_node, NodePath p_path, PathSentCache *psc, int p_target); Error _encode_and_compress_variant(const Variant &p_variant, uint8_t *p_buffer, int &r_len); @@ -84,7 +112,6 @@ protected: public: enum NetworkCommands { NETWORK_COMMAND_REMOTE_CALL = 0, - NETWORK_COMMAND_REMOTE_SET, NETWORK_COMMAND_SIMPLIFY_PATH, NETWORK_COMMAND_CONFIRM_PATH, NETWORK_COMMAND_RAW, @@ -101,16 +128,6 @@ public: NETWORK_NAME_ID_COMPRESSION_16, }; - enum RPCMode { - RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default) - RPC_MODE_REMOTE, // Using rpc() on it will call method / set property in all remote peers - RPC_MODE_MASTER, // Using rpc() on it will call method on wherever the master is, be it local or remote - RPC_MODE_PUPPET, // Using rpc() on it will call method for all puppets - RPC_MODE_REMOTESYNC, // Using rpc() on it will call method / set property in all remote peers and locally - RPC_MODE_MASTERSYNC, // Using rpc() on it will call method / set property in the master peer and locally - RPC_MODE_PUPPETSYNC, // Using rpc() on it will call method / set property in all puppets peers and locally - }; - void poll(); void clear(); void set_root_node(Node *p_node); @@ -121,8 +138,6 @@ public: // Called by Node.rpc void rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount); - // Called by Node.rset - void rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value); void _add_peer(int p_id); void _del_peer(int p_id); diff --git a/core/io/net_socket.h b/core/io/net_socket.h index bc09477693..98ff9562d9 100644 --- a/core/io/net_socket.h +++ b/core/io/net_socket.h @@ -55,26 +55,27 @@ public: virtual Error open(Type p_type, IP::Type &ip_type) = 0; virtual void close() = 0; - virtual Error bind(IP_Address p_addr, uint16_t p_port) = 0; + virtual Error bind(IPAddress p_addr, uint16_t p_port) = 0; virtual Error listen(int p_max_pending) = 0; - virtual Error connect_to_host(IP_Address p_addr, uint16_t p_port) = 0; + virtual Error connect_to_host(IPAddress p_addr, uint16_t p_port) = 0; virtual Error poll(PollType p_type, int timeout) const = 0; virtual Error recv(uint8_t *p_buffer, int p_len, int &r_read) = 0; - virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port, bool p_peek = false) = 0; + virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddress &r_ip, uint16_t &r_port, bool p_peek = false) = 0; virtual Error send(const uint8_t *p_buffer, int p_len, int &r_sent) = 0; - virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) = 0; - virtual Ref<NetSocket> accept(IP_Address &r_ip, uint16_t &r_port) = 0; + virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port) = 0; + virtual Ref<NetSocket> accept(IPAddress &r_ip, uint16_t &r_port) = 0; virtual bool is_open() const = 0; virtual int get_available_bytes() const = 0; + virtual Error get_socket_address(IPAddress *r_ip, uint16_t *r_port) const = 0; virtual Error set_broadcasting_enabled(bool p_enabled) = 0; // Returns OK if the socket option has been set successfully. virtual void set_blocking_enabled(bool p_enabled) = 0; virtual void set_ipv6_only_enabled(bool p_enabled) = 0; virtual void set_tcp_no_delay_enabled(bool p_enabled) = 0; virtual void set_reuse_address_enabled(bool p_enabled) = 0; - virtual Error join_multicast_group(const IP_Address &p_multi_address, String p_if_name) = 0; - virtual Error leave_multicast_group(const IP_Address &p_multi_address, String p_if_name) = 0; + virtual Error join_multicast_group(const IPAddress &p_multi_address, String p_if_name) = 0; + virtual Error leave_multicast_group(const IPAddress &p_multi_address, String p_if_name) = 0; }; #endif // NET_SOCKET_H diff --git a/core/io/packed_data_container.cpp b/core/io/packed_data_container.cpp index a0b97772e6..cf6a0b6027 100644 --- a/core/io/packed_data_container.cpp +++ b/core/io/packed_data_container.cpp @@ -123,6 +123,7 @@ Variant PackedDataContainer::_get_at_ofs(uint32_t p_ofs, const uint8_t *p_buf, b uint32_t PackedDataContainer::_type_at_ofs(uint32_t p_ofs) const { const uint8_t *rd = data.ptr(); + ERR_FAIL_COND_V(!rd, 0); const uint8_t *r = &rd[p_ofs]; uint32_t type = decode_uint32(r); @@ -149,6 +150,10 @@ int PackedDataContainer::_size(uint32_t p_ofs) const { Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, bool &err) const { const uint8_t *rd = data.ptr(); + if (!rd) { + err = true; + ERR_FAIL_COND_V(!rd, Variant()); + } const uint8_t *r = &rd[p_ofs]; uint32_t type = decode_uint32(r); @@ -222,10 +227,10 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd case Variant::VECTOR3: case Variant::TRANSFORM2D: case Variant::PLANE: - case Variant::QUAT: + case Variant::QUATERNION: case Variant::AABB: case Variant::BASIS: - case Variant::TRANSFORM: + case Variant::TRANSFORM3D: case Variant::PACKED_BYTE_ARRAY: case Variant::PACKED_INT32_ARRAY: case Variant::PACKED_INT64_ARRAY: @@ -317,7 +322,7 @@ Error PackedDataContainer::pack(const Variant &p_data) { datalen = tmpdata.size(); data.resize(tmpdata.size()); uint8_t *w = data.ptrw(); - copymem(w, tmpdata.ptr(), tmpdata.size()); + memcpy(w, tmpdata.ptr(), tmpdata.size()); return OK; } diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp index 3f46f2706e..f951a5158c 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -45,7 +45,7 @@ void PacketPeerUDP::set_broadcast_enabled(bool p_enabled) { } } -Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_if_name) { +Error PacketPeerUDP::join_multicast_group(IPAddress p_multi_address, String p_if_name) { ERR_FAIL_COND_V(udp_server, ERR_LOCKED); ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); ERR_FAIL_COND_V(!p_multi_address.is_valid(), ERR_INVALID_PARAMETER); @@ -60,7 +60,7 @@ Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_i return _sock->join_multicast_group(p_multi_address, p_if_name); } -Error PacketPeerUDP::leave_multicast_group(IP_Address p_multi_address, String p_if_name) { +Error PacketPeerUDP::leave_multicast_group(IPAddress p_multi_address, String p_if_name) { ERR_FAIL_COND_V(udp_server, ERR_LOCKED); ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); ERR_FAIL_COND_V(!_sock->is_open(), ERR_UNCONFIGURED); @@ -72,7 +72,7 @@ String PacketPeerUDP::_get_packet_ip() const { } Error PacketPeerUDP::_set_dest_address(const String &p_address, int p_port) { - IP_Address ip; + IPAddress ip; if (p_address.is_valid_ip_address()) { ip = p_address; } else { @@ -159,10 +159,11 @@ int PacketPeerUDP::get_max_packet_size() const { return 512; // uhm maybe not } -Error PacketPeerUDP::listen(int p_port, const IP_Address &p_bind_address, int p_recv_buffer_size) { +Error PacketPeerUDP::bind(int p_port, const IPAddress &p_bind_address, int p_recv_buffer_size) { ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE); ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The local port number must be between 0 and 65535 (inclusive)."); Error err; IP::Type ip_type = IP::TYPE_ANY; @@ -189,7 +190,7 @@ Error PacketPeerUDP::listen(int p_port, const IP_Address &p_bind_address, int p_ return OK; } -Error PacketPeerUDP::connect_shared_socket(Ref<NetSocket> p_sock, IP_Address p_ip, uint16_t p_port, UDPServer *p_server) { +Error PacketPeerUDP::connect_shared_socket(Ref<NetSocket> p_sock, IPAddress p_ip, uint16_t p_port, UDPServer *p_server) { udp_server = p_server; connected = true; _sock = p_sock; @@ -206,10 +207,11 @@ void PacketPeerUDP::disconnect_shared_socket() { close(); } -Error PacketPeerUDP::connect_to_host(const IP_Address &p_host, int p_port) { +Error PacketPeerUDP::connect_to_host(const IPAddress &p_host, int p_port) { ERR_FAIL_COND_V(udp_server, ERR_LOCKED); ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); ERR_FAIL_COND_V(!p_host.is_valid(), ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V_MSG(p_port < 1 || p_port > 65535, ERR_INVALID_PARAMETER, "The remote port number must be between 1 and 65535 (inclusive)."); Error err; @@ -274,7 +276,7 @@ Error PacketPeerUDP::_poll() { Error err; int read; - IP_Address ip; + IPAddress ip; uint16_t port; while (true) { @@ -304,7 +306,7 @@ Error PacketPeerUDP::_poll() { return OK; } -Error PacketPeerUDP::store_packet(IP_Address p_ip, uint32_t p_port, uint8_t *p_buf, int p_buf_size) { +Error PacketPeerUDP::store_packet(IPAddress p_ip, uint32_t p_port, uint8_t *p_buf, int p_buf_size) { if (rb.space_left() < p_buf_size + 24) { return ERR_OUT_OF_MEMORY; } @@ -316,11 +318,11 @@ Error PacketPeerUDP::store_packet(IP_Address p_ip, uint32_t p_port, uint8_t *p_b return OK; } -bool PacketPeerUDP::is_listening() const { +bool PacketPeerUDP::is_bound() const { return _sock.is_valid() && _sock->is_open(); } -IP_Address PacketPeerUDP::get_packet_address() const { +IPAddress PacketPeerUDP::get_packet_address() const { return packet_ip; } @@ -328,21 +330,28 @@ int PacketPeerUDP::get_packet_port() const { return packet_port; } -void PacketPeerUDP::set_dest_address(const IP_Address &p_address, int p_port) { +int PacketPeerUDP::get_local_port() const { + uint16_t local_port; + _sock->get_socket_address(nullptr, &local_port); + return local_port; +} + +void PacketPeerUDP::set_dest_address(const IPAddress &p_address, int p_port) { ERR_FAIL_COND_MSG(connected, "Destination address cannot be set for connected sockets"); peer_addr = p_address; peer_port = p_port; } void PacketPeerUDP::_bind_methods() { - ClassDB::bind_method(D_METHOD("listen", "port", "bind_address", "recv_buf_size"), &PacketPeerUDP::listen, DEFVAL("*"), DEFVAL(65536)); + ClassDB::bind_method(D_METHOD("bind", "port", "bind_address", "recv_buf_size"), &PacketPeerUDP::bind, DEFVAL("*"), DEFVAL(65536)); ClassDB::bind_method(D_METHOD("close"), &PacketPeerUDP::close); ClassDB::bind_method(D_METHOD("wait"), &PacketPeerUDP::wait); - ClassDB::bind_method(D_METHOD("is_listening"), &PacketPeerUDP::is_listening); + ClassDB::bind_method(D_METHOD("is_bound"), &PacketPeerUDP::is_bound); ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port"), &PacketPeerUDP::connect_to_host); ClassDB::bind_method(D_METHOD("is_connected_to_host"), &PacketPeerUDP::is_connected_to_host); ClassDB::bind_method(D_METHOD("get_packet_ip"), &PacketPeerUDP::_get_packet_ip); ClassDB::bind_method(D_METHOD("get_packet_port"), &PacketPeerUDP::get_packet_port); + ClassDB::bind_method(D_METHOD("get_local_port"), &PacketPeerUDP::get_local_port); ClassDB::bind_method(D_METHOD("set_dest_address", "host", "port"), &PacketPeerUDP::_set_dest_address); ClassDB::bind_method(D_METHOD("set_broadcast_enabled", "enabled"), &PacketPeerUDP::set_broadcast_enabled); ClassDB::bind_method(D_METHOD("join_multicast_group", "multicast_address", "interface_name"), &PacketPeerUDP::join_multicast_group); diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h index 4bac6994fc..40d3c44e40 100644 --- a/core/io/packet_peer_udp.h +++ b/core/io/packet_peer_udp.h @@ -48,11 +48,11 @@ protected: RingBuffer<uint8_t> rb; uint8_t recv_buffer[PACKET_BUFFER_SIZE]; uint8_t packet_buffer[PACKET_BUFFER_SIZE]; - IP_Address packet_ip; + IPAddress packet_ip; int packet_port = 0; int queue_count = 0; - IP_Address peer_addr; + IPAddress peer_addr; int peer_port = 0; bool connected = false; bool blocking = true; @@ -70,28 +70,29 @@ protected: public: void set_blocking_mode(bool p_enable); - Error listen(int p_port, const IP_Address &p_bind_address = IP_Address("*"), int p_recv_buffer_size = 65536); + Error bind(int p_port, const IPAddress &p_bind_address = IPAddress("*"), int p_recv_buffer_size = 65536); void close(); Error wait(); - bool is_listening() const; + bool is_bound() const; - Error connect_shared_socket(Ref<NetSocket> p_sock, IP_Address p_ip, uint16_t p_port, UDPServer *ref); // Used by UDPServer + Error connect_shared_socket(Ref<NetSocket> p_sock, IPAddress p_ip, uint16_t p_port, UDPServer *ref); // Used by UDPServer void disconnect_shared_socket(); // Used by UDPServer - Error store_packet(IP_Address p_ip, uint32_t p_port, uint8_t *p_buf, int p_buf_size); // Used internally and by UDPServer - Error connect_to_host(const IP_Address &p_host, int p_port); + Error store_packet(IPAddress p_ip, uint32_t p_port, uint8_t *p_buf, int p_buf_size); // Used internally and by UDPServer + Error connect_to_host(const IPAddress &p_host, int p_port); bool is_connected_to_host() const; - IP_Address get_packet_address() const; + IPAddress get_packet_address() const; int get_packet_port() const; - void set_dest_address(const IP_Address &p_address, int p_port); + int get_local_port() const; + void set_dest_address(const IPAddress &p_address, int p_port); Error put_packet(const uint8_t *p_buffer, int p_buffer_size) override; Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) override; int get_available_packet_count() const override; int get_max_packet_size() const override; void set_broadcast_enabled(bool p_enabled); - Error join_multicast_group(IP_Address p_multi_address, String p_if_name); - Error leave_multicast_group(IP_Address p_multi_address, String p_if_name); + Error join_multicast_group(IPAddress p_multi_address, String p_if_name); + Error leave_multicast_group(IPAddress p_multi_address, String p_if_name); PacketPeerUDP(); ~PacketPeerUDP(); diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp index a0697ca18b..cadb02b5dd 100644 --- a/core/io/pck_packer.cpp +++ b/core/io/pck_packer.cpp @@ -120,7 +120,7 @@ Error PCKPacker::add_file(const String &p_file, const String &p_src, bool p_encr pf.path = p_file; pf.src_path = p_src; pf.ofs = ofs; - pf.size = f->get_len(); + pf.size = f->get_length(); Vector<uint8_t> data = FileAccess::get_file_as_array(p_src); { @@ -236,7 +236,7 @@ Error PCKPacker::flush(bool p_verbose) { } while (to_write > 0) { - int read = src->get_buffer(buf, MIN(to_write, buf_max)); + uint64_t read = src->get_buffer(buf, MIN(to_write, buf_max)); ftmp->store_buffer(buf, read); to_write -= read; } diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 8560e2abc7..d46e9edafa 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -110,6 +110,12 @@ String Resource::get_name() const { return name; } +void Resource::update_configuration_warning() { + if (_update_configuration_warning) { + _update_configuration_warning(); + } +} + bool Resource::editor_can_reload_from_file() { return true; //by default yes } @@ -320,6 +326,7 @@ void Resource::setup_local_to_scene() { } Node *(*Resource::_get_local_scene_func)() = nullptr; +void (*Resource::_update_configuration_warning)() = nullptr; void Resource::set_as_translation_remapped(bool p_remapped) { if (remapped_list.in_list() == p_remapped) { diff --git a/core/io/resource.h b/core/io/resource.h index ae18ac0c8a..75a9f928f8 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -88,7 +88,9 @@ protected: public: static Node *(*_get_local_scene_func)(); //used by editor + static void (*_update_configuration_warning)(); //used by editor + void update_configuration_warning(); virtual bool editor_can_reload_from_file(); virtual void reset_state(); //for resources that use variable amount of properties, either via _validate_property or _get_property_list, this function needs to be implemented to correctly clear state virtual Error copy_from(const Ref<Resource> &p_resource); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index c4eb2a20bb..385f15c0cf 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -51,7 +51,7 @@ enum { VARIANT_RECT2 = 11, VARIANT_VECTOR3 = 12, VARIANT_PLANE = 13, - VARIANT_QUAT = 14, + VARIANT_QUATERNION = 14, VARIANT_AABB = 15, VARIANT_MATRIX3 = 16, VARIANT_TRANSFORM = 17, @@ -199,8 +199,8 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { v.d = f->get_real(); r_v = v; } break; - case VARIANT_QUAT: { - Quat v; + case VARIANT_QUATERNION: { + Quaternion v; v.x = f->get_real(); v.y = f->get_real(); v.z = f->get_real(); @@ -245,7 +245,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { } break; case VARIANT_TRANSFORM: { - Transform v; + Transform3D v; v.basis.elements[0].x = f->get_real(); v.basis.elements[0].y = f->get_real(); v.basis.elements[0].z = f->get_real(); @@ -851,7 +851,7 @@ void ResourceLoaderBinary::open(FileAccess *p_f) { bool big_endian = f->get_32(); bool use_real64 = f->get_32(); - f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian + f->set_big_endian(big_endian != 0); //read big endian if saved as big endian uint32_t ver_major = f->get_32(); uint32_t ver_minor = f->get_32(); @@ -948,7 +948,7 @@ String ResourceLoaderBinary::recognize(FileAccess *p_f) { bool big_endian = f->get_32(); f->get_32(); // use_real64 - f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian + f->set_big_endian(big_endian != 0); //read big endian if saved as big endian uint32_t ver_major = f->get_32(); f->get_32(); // ver_minor @@ -1097,13 +1097,13 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons bool big_endian = f->get_32(); bool use_real64 = f->get_32(); - f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian + f->set_big_endian(big_endian != 0); //read big endian if saved as big endian #ifdef BIG_ENDIAN_ENABLED fw->store_32(!big_endian); #else fw->store_32(big_endian); #endif - fw->set_endian_swap(big_endian != 0); + fw->set_big_endian(big_endian != 0); fw->store_32(use_real64); //use real64 uint32_t ver_major = f->get_32(); @@ -1157,8 +1157,8 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons save_ustring(fw, get_ustring(f)); //type - size_t md_ofs = f->get_position(); - size_t importmd_ofs = f->get_64(); + uint64_t md_ofs = f->get_position(); + uint64_t importmd_ofs = f->get_64(); fw->store_64(0); //metadata offset for (int i = 0; i < 14; i++) { @@ -1371,9 +1371,9 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia f->store_real(val.d); } break; - case Variant::QUAT: { - f->store_32(VARIANT_QUAT); - Quat val = p_property; + case Variant::QUATERNION: { + f->store_32(VARIANT_QUATERNION); + Quaternion val = p_property; f->store_real(val.x); f->store_real(val.y); f->store_real(val.z); @@ -1416,9 +1416,9 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia f->store_real(val.elements[2].z); } break; - case Variant::TRANSFORM: { + case Variant::TRANSFORM3D: { f->store_32(VARIANT_TRANSFORM); - Transform val = p_property; + Transform3D val = p_property; f->store_real(val.basis.elements[0].x); f->store_real(val.basis.elements[0].y); f->store_real(val.basis.elements[0].z); @@ -1798,7 +1798,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p if (big_endian) { f->store_32(1); - f->set_endian_swap(true); + f->set_big_endian(true); } else { f->store_32(0); } diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index 5ca0eb884a..b503655edd 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -192,6 +192,34 @@ bool ResourceFormatImporter::recognize_path(const String &p_path, const String & return FileAccess::exists(p_path + ".import"); } +Error ResourceFormatImporter::get_import_order_threads_and_importer(const String &p_path, int &r_order, bool &r_can_threads, String &r_importer) const { + r_order = 0; + r_importer = ""; + + r_can_threads = false; + Ref<ResourceImporter> importer; + + if (FileAccess::exists(p_path + ".import")) { + PathAndType pat; + Error err = _get_path_and_type(p_path, pat); + + if (err == OK) { + importer = get_importer_by_name(pat.importer); + } + } else { + importer = get_importer_by_extension(p_path.get_extension().to_lower()); + } + + if (importer.is_valid()) { + r_order = importer->get_import_order(); + r_importer = importer->get_importer_name(); + r_can_threads = importer->can_import_threaded(); + return OK; + } else { + return ERR_INVALID_PARAMETER; + } +} + int ResourceFormatImporter::get_import_order(const String &p_path) const { Ref<ResourceImporter> importer; diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index eeb486073e..a14d6ba52c 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -72,6 +72,8 @@ public: virtual int get_import_order(const String &p_path) const; + Error get_import_order_threads_and_importer(const String &p_path, int &r_order, bool &r_can_threads, String &r_importer) const; + String get_internal_resource_path(const String &p_path) const; void get_internal_resource_path_list(const String &p_path, List<String> *r_paths); @@ -126,6 +128,9 @@ public: virtual String get_option_group_file() const { return String(); } virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) = 0; + virtual bool can_import_threaded() const { return true; } + virtual void import_threaded_begin() {} + virtual void import_threaded_end() {} virtual Error import_group_file(const String &p_group_file, const Map<String, Map<StringName, Variant>> &p_source_file_options, const Map<String, String> &p_base_paths) { return ERR_UNAVAILABLE; } virtual bool are_import_settings_valid(const String &p_path) const { return true; } diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index dcf71bb4a9..b48c48b1bc 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -114,25 +114,24 @@ void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions) } RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { + // Check user-defined loader if there's any. Hard fail if it returns an error. if (get_script_instance() && get_script_instance()->has_method("load")) { Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads, p_cache_mode); - if (res.get_type() == Variant::INT) { + if (res.get_type() == Variant::INT) { // Error code, abort. if (r_error) { *r_error = (Error)res.operator int64_t(); } - - } else { + return RES(); + } else { // Success, pass on result. if (r_error) { *r_error = OK; } return res; } - - return res; } - ERR_FAIL_V_MSG(RES(), "Failed to load resource '" + p_path + "', ResourceFormatLoader::load was not implemented for this resource type."); + ERR_FAIL_V_MSG(RES(), "Failed to load resource '" + p_path + "'. ResourceFormatLoader::load was not implemented for this resource type."); } void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { @@ -355,7 +354,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String & ThreadLoadTask &load_task = thread_load_tasks[local_path]; - if (load_task.resource.is_null()) { //needs to be loaded in thread + if (load_task.resource.is_null()) { //needs to be loaded in thread load_task.semaphore = memnew(Semaphore); if (thread_loading_count < thread_load_max) { @@ -868,7 +867,7 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem continue; } - String l = res_remaps[i].right(split + 1).strip_edges(); + String l = res_remaps[i].substr(split + 1).strip_edges(); if (l == locale) { // Exact match. new_path = res_remaps[i].left(split); break; diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index 8407d55196..ee5e9eca0c 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -108,8 +108,8 @@ Array StreamPeer::_get_partial_data(int p_bytes) { return ret; } -void StreamPeer::set_big_endian(bool p_enable) { - big_endian = p_enable; +void StreamPeer::set_big_endian(bool p_big_endian) { + big_endian = p_big_endian; } bool StreamPeer::is_big_endian_enabled() const { @@ -433,7 +433,7 @@ Error StreamPeerBuffer::put_data(const uint8_t *p_data, int p_bytes) { } uint8_t *w = data.ptrw(); - copymem(&w[pointer], p_data, p_bytes); + memcpy(&w[pointer], p_data, p_bytes); pointer += p_bytes; return OK; @@ -466,7 +466,7 @@ Error StreamPeerBuffer::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_ } const uint8_t *r = data.ptr(); - copymem(p_buffer, r + pointer, r_received); + memcpy(p_buffer, r + pointer, r_received); pointer += r_received; // FIXME: return what? OK or ERR_* diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h index dadedbd2dc..1e1a3e890c 100644 --- a/core/io/stream_peer.h +++ b/core/io/stream_peer.h @@ -58,7 +58,7 @@ public: virtual int get_available_bytes() const = 0; - void set_big_endian(bool p_enable); + void set_big_endian(bool p_big_endian); bool is_big_endian_enabled() const; void put_8(int8_t p_val); diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index 760710a9eb..5b794274ca 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -56,7 +56,7 @@ Error StreamPeerTCP::_poll_connection() { return ERR_CONNECTION_ERROR; } -void StreamPeerTCP::accept_socket(Ref<NetSocket> p_sock, IP_Address p_host, uint16_t p_port) { +void StreamPeerTCP::accept_socket(Ref<NetSocket> p_sock, IPAddress p_host, uint16_t p_port) { _sock = p_sock; _sock->set_blocking_enabled(false); @@ -67,21 +67,40 @@ void StreamPeerTCP::accept_socket(Ref<NetSocket> p_sock, IP_Address p_host, uint peer_port = p_port; } -Error StreamPeerTCP::connect_to_host(const IP_Address &p_host, uint16_t p_port) { +Error StreamPeerTCP::bind(int p_port, const IPAddress &p_host) { ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE); - ERR_FAIL_COND_V(!p_host.is_valid(), ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The local port number must be between 0 and 65535 (inclusive)."); - Error err; IP::Type ip_type = p_host.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; + if (p_host.is_wildcard()) { + ip_type = IP::TYPE_ANY; + } + Error err = _sock->open(NetSocket::TYPE_TCP, ip_type); + if (err != OK) { + return err; + } + _sock->set_blocking_enabled(false); + return _sock->bind(p_host, p_port); +} - err = _sock->open(NetSocket::TYPE_TCP, ip_type); - ERR_FAIL_COND_V(err != OK, FAILED); +Error StreamPeerTCP::connect_to_host(const IPAddress &p_host, int p_port) { + ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); + ERR_FAIL_COND_V(status != STATUS_NONE, ERR_ALREADY_IN_USE); + ERR_FAIL_COND_V(!p_host.is_valid(), ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V_MSG(p_port < 1 || p_port > 65535, ERR_INVALID_PARAMETER, "The remote port number must be between 1 and 65535 (inclusive)."); - _sock->set_blocking_enabled(false); + if (!_sock->is_open()) { + IP::Type ip_type = p_host.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; + Error err = _sock->open(NetSocket::TYPE_TCP, ip_type); + if (err != OK) { + return err; + } + _sock->set_blocking_enabled(false); + } timeout = OS::get_singleton()->get_ticks_msec() + (((uint64_t)GLOBAL_GET("network/limits/tcp/connect_timeout_seconds")) * 1000); - err = _sock->connect_to_host(p_host, p_port); + Error err = _sock->connect_to_host(p_host, p_port); if (err == OK) { status = STATUS_CONNECTED; @@ -264,7 +283,7 @@ void StreamPeerTCP::disconnect_from_host() { timeout = 0; status = STATUS_NONE; - peer_host = IP_Address(); + peer_host = IPAddress(); peer_port = 0; } @@ -296,16 +315,22 @@ int StreamPeerTCP::get_available_bytes() const { return _sock->get_available_bytes(); } -IP_Address StreamPeerTCP::get_connected_host() const { +IPAddress StreamPeerTCP::get_connected_host() const { return peer_host; } -uint16_t StreamPeerTCP::get_connected_port() const { +int StreamPeerTCP::get_connected_port() const { return peer_port; } +int StreamPeerTCP::get_local_port() const { + uint16_t local_port; + _sock->get_socket_address(nullptr, &local_port); + return local_port; +} + Error StreamPeerTCP::_connect(const String &p_address, int p_port) { - IP_Address ip; + IPAddress ip; if (p_address.is_valid_ip_address()) { ip = p_address; } else { @@ -319,11 +344,13 @@ Error StreamPeerTCP::_connect(const String &p_address, int p_port) { } void StreamPeerTCP::_bind_methods() { + ClassDB::bind_method(D_METHOD("bind", "port", "host"), &StreamPeerTCP::bind, DEFVAL("*")); ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port"), &StreamPeerTCP::_connect); ClassDB::bind_method(D_METHOD("is_connected_to_host"), &StreamPeerTCP::is_connected_to_host); ClassDB::bind_method(D_METHOD("get_status"), &StreamPeerTCP::get_status); ClassDB::bind_method(D_METHOD("get_connected_host"), &StreamPeerTCP::get_connected_host); ClassDB::bind_method(D_METHOD("get_connected_port"), &StreamPeerTCP::get_connected_port); + ClassDB::bind_method(D_METHOD("get_local_port"), &StreamPeerTCP::get_local_port); ClassDB::bind_method(D_METHOD("disconnect_from_host"), &StreamPeerTCP::disconnect_from_host); ClassDB::bind_method(D_METHOD("set_no_delay", "enabled"), &StreamPeerTCP::set_no_delay); diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h index 10b90908d4..a2a7f447d8 100644 --- a/core/io/stream_peer_tcp.h +++ b/core/io/stream_peer_tcp.h @@ -52,7 +52,7 @@ protected: Ref<NetSocket> _sock; uint64_t timeout = 0; Status status = STATUS_NONE; - IP_Address peer_host; + IPAddress peer_host; uint16_t peer_port = 0; Error _connect(const String &p_address, int p_port); @@ -63,12 +63,14 @@ protected: static void _bind_methods(); public: - void accept_socket(Ref<NetSocket> p_sock, IP_Address p_host, uint16_t p_port); + void accept_socket(Ref<NetSocket> p_sock, IPAddress p_host, uint16_t p_port); - Error connect_to_host(const IP_Address &p_host, uint16_t p_port); + Error bind(int p_port, const IPAddress &p_host); + Error connect_to_host(const IPAddress &p_host, int p_port); bool is_connected_to_host() const; - IP_Address get_connected_host() const; - uint16_t get_connected_port() const; + IPAddress get_connected_host() const; + int get_connected_port() const; + int get_local_port() const; void disconnect_from_host(); int get_available_bytes() const override; diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp index 323d2bbd7f..b760a9ef80 100644 --- a/core/io/tcp_server.cpp +++ b/core/io/tcp_server.cpp @@ -30,18 +30,20 @@ #include "tcp_server.h" -void TCP_Server::_bind_methods() { - ClassDB::bind_method(D_METHOD("listen", "port", "bind_address"), &TCP_Server::listen, DEFVAL("*")); - ClassDB::bind_method(D_METHOD("is_connection_available"), &TCP_Server::is_connection_available); - ClassDB::bind_method(D_METHOD("is_listening"), &TCP_Server::is_listening); - ClassDB::bind_method(D_METHOD("take_connection"), &TCP_Server::take_connection); - ClassDB::bind_method(D_METHOD("stop"), &TCP_Server::stop); +void TCPServer::_bind_methods() { + ClassDB::bind_method(D_METHOD("listen", "port", "bind_address"), &TCPServer::listen, DEFVAL("*")); + ClassDB::bind_method(D_METHOD("is_connection_available"), &TCPServer::is_connection_available); + ClassDB::bind_method(D_METHOD("is_listening"), &TCPServer::is_listening); + ClassDB::bind_method(D_METHOD("get_local_port"), &TCPServer::get_local_port); + ClassDB::bind_method(D_METHOD("take_connection"), &TCPServer::take_connection); + ClassDB::bind_method(D_METHOD("stop"), &TCPServer::stop); } -Error TCP_Server::listen(uint16_t p_port, const IP_Address &p_bind_address) { +Error TCPServer::listen(uint16_t p_port, const IPAddress &p_bind_address) { ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE); ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The local port number must be between 0 and 65535 (inclusive)."); Error err; IP::Type ip_type = IP::TYPE_ANY; @@ -74,13 +76,19 @@ Error TCP_Server::listen(uint16_t p_port, const IP_Address &p_bind_address) { return OK; } -bool TCP_Server::is_listening() const { +int TCPServer::get_local_port() const { + uint16_t local_port; + _sock->get_socket_address(nullptr, &local_port); + return local_port; +} + +bool TCPServer::is_listening() const { ERR_FAIL_COND_V(!_sock.is_valid(), false); return _sock->is_open(); } -bool TCP_Server::is_connection_available() const { +bool TCPServer::is_connection_available() const { ERR_FAIL_COND_V(!_sock.is_valid(), false); if (!_sock->is_open()) { @@ -91,14 +99,14 @@ bool TCP_Server::is_connection_available() const { return (err == OK); } -Ref<StreamPeerTCP> TCP_Server::take_connection() { +Ref<StreamPeerTCP> TCPServer::take_connection() { Ref<StreamPeerTCP> conn; if (!is_connection_available()) { return conn; } Ref<NetSocket> ns; - IP_Address ip; + IPAddress ip; uint16_t port = 0; ns = _sock->accept(ip, port); if (!ns.is_valid()) { @@ -110,16 +118,16 @@ Ref<StreamPeerTCP> TCP_Server::take_connection() { return conn; } -void TCP_Server::stop() { +void TCPServer::stop() { if (_sock.is_valid()) { _sock->close(); } } -TCP_Server::TCP_Server() : +TCPServer::TCPServer() : _sock(Ref<NetSocket>(NetSocket::create())) { } -TCP_Server::~TCP_Server() { +TCPServer::~TCPServer() { stop(); } diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h index f06ddd2d99..abefa53c6f 100644 --- a/core/io/tcp_server.h +++ b/core/io/tcp_server.h @@ -36,8 +36,8 @@ #include "core/io/stream_peer.h" #include "core/io/stream_peer_tcp.h" -class TCP_Server : public Reference { - GDCLASS(TCP_Server, Reference); +class TCPServer : public Reference { + GDCLASS(TCPServer, Reference); protected: enum { @@ -48,15 +48,16 @@ protected: static void _bind_methods(); public: - Error listen(uint16_t p_port, const IP_Address &p_bind_address = IP_Address("*")); + Error listen(uint16_t p_port, const IPAddress &p_bind_address = IPAddress("*")); + int get_local_port() const; bool is_listening() const; bool is_connection_available() const; Ref<StreamPeerTCP> take_connection(); void stop(); // Stop listening - TCP_Server(); - ~TCP_Server(); + TCPServer(); + ~TCPServer(); }; #endif // TCP_SERVER_H diff --git a/core/io/udp_server.cpp b/core/io/udp_server.cpp index f56fb431ef..6a1af0c2a9 100644 --- a/core/io/udp_server.cpp +++ b/core/io/udp_server.cpp @@ -34,6 +34,7 @@ void UDPServer::_bind_methods() { ClassDB::bind_method(D_METHOD("listen", "port", "bind_address"), &UDPServer::listen, DEFVAL("*")); ClassDB::bind_method(D_METHOD("poll"), &UDPServer::poll); ClassDB::bind_method(D_METHOD("is_connection_available"), &UDPServer::is_connection_available); + ClassDB::bind_method(D_METHOD("get_local_port"), &UDPServer::get_local_port); ClassDB::bind_method(D_METHOD("is_listening"), &UDPServer::is_listening); ClassDB::bind_method(D_METHOD("take_connection"), &UDPServer::take_connection); ClassDB::bind_method(D_METHOD("stop"), &UDPServer::stop); @@ -49,7 +50,7 @@ Error UDPServer::poll() { } Error err; int read; - IP_Address ip; + IPAddress ip; uint16_t port; while (true) { err = _sock->recvfrom(recv_buffer, sizeof(recv_buffer), read, ip, port); @@ -86,10 +87,11 @@ Error UDPServer::poll() { return OK; } -Error UDPServer::listen(uint16_t p_port, const IP_Address &p_bind_address) { +Error UDPServer::listen(uint16_t p_port, const IPAddress &p_bind_address) { ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE); ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The local port number must be between 0 and 65535 (inclusive)."); Error err; IP::Type ip_type = IP::TYPE_ANY; @@ -112,11 +114,15 @@ Error UDPServer::listen(uint16_t p_port, const IP_Address &p_bind_address) { stop(); return err; } - bind_address = p_bind_address; - bind_port = p_port; return OK; } +int UDPServer::get_local_port() const { + uint16_t local_port; + _sock->get_socket_address(nullptr, &local_port); + return local_port; +} + bool UDPServer::is_listening() const { ERR_FAIL_COND_V(!_sock.is_valid(), false); @@ -162,7 +168,7 @@ Ref<PacketPeerUDP> UDPServer::take_connection() { return peer.peer; } -void UDPServer::remove_peer(IP_Address p_ip, int p_port) { +void UDPServer::remove_peer(IPAddress p_ip, int p_port) { Peer peer; peer.ip = p_ip; peer.port = p_port; @@ -176,8 +182,6 @@ void UDPServer::stop() { if (_sock.is_valid()) { _sock->close(); } - bind_port = 0; - bind_address = IP_Address(); List<Peer>::Element *E = peers.front(); while (E) { E->get().peer->disconnect_shared_socket(); diff --git a/core/io/udp_server.h b/core/io/udp_server.h index bbd2f951c9..60d03f37f0 100644 --- a/core/io/udp_server.h +++ b/core/io/udp_server.h @@ -44,7 +44,7 @@ protected: struct Peer { PacketPeerUDP *peer; - IP_Address ip; + IPAddress ip; uint16_t port = 0; bool operator==(const Peer &p_other) const { @@ -53,21 +53,18 @@ protected: }; uint8_t recv_buffer[PACKET_BUFFER_SIZE]; - int bind_port = 0; - IP_Address bind_address; - List<Peer> peers; List<Peer> pending; int max_pending_connections = 16; Ref<NetSocket> _sock; - static void _bind_methods(); public: - void remove_peer(IP_Address p_ip, int p_port); - Error listen(uint16_t p_port, const IP_Address &p_bind_address = IP_Address("*")); + void remove_peer(IPAddress p_ip, int p_port); + Error listen(uint16_t p_port, const IPAddress &p_bind_address = IPAddress("*")); Error poll(); + int get_local_port() const; bool is_listening() const; bool is_connection_available() const; void set_max_pending_connections(int p_max); diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index d5eb32513b..938d93a01b 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -75,7 +75,7 @@ void XMLParser::_parse_closing_xml_element() { ++P; const char *pBeginClose = P; - while (*P != '>') { + while (*P && *P != '>') { ++P; } @@ -83,7 +83,10 @@ void XMLParser::_parse_closing_xml_element() { #ifdef DEBUG_XML print_line("XML CLOSE: " + node_name); #endif - ++P; + + if (*P) { + ++P; + } } void XMLParser::_ignore_definition() { @@ -91,11 +94,14 @@ void XMLParser::_ignore_definition() { char *F = P; // move until end marked with '>' reached - while (*P != '>') { + while (*P && *P != '>') { ++P; } node_name.parse_utf8(F, P - F); - ++P; + + if (*P) { + ++P; + } } bool XMLParser::_parse_cdata() { @@ -113,6 +119,7 @@ bool XMLParser::_parse_cdata() { } if (!*P) { + node_name = ""; return true; } @@ -131,10 +138,9 @@ bool XMLParser::_parse_cdata() { } if (cDataEnd) { - node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin)); - } else { - node_name = ""; + cDataEnd = P; } + node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin)); #ifdef DEBUG_XML print_line("XML CDATA: " + node_name); #endif @@ -146,24 +152,45 @@ void XMLParser::_parse_comment() { node_type = NODE_COMMENT; P += 1; - char *pCommentBegin = P; + char *pEndOfInput = data + length; + char *pCommentBegin; + char *pCommentEnd; - int count = 1; - - // move until end of comment reached - while (count) { - if (*P == '>') { - --count; - } else if (*P == '<') { - ++count; + if (P + 1 < pEndOfInput && P[0] == '-' && P[1] == '-') { + // Comment, use '-->' as end. + pCommentBegin = P + 2; + for (pCommentEnd = pCommentBegin; pCommentEnd + 2 < pEndOfInput; pCommentEnd++) { + if (pCommentEnd[0] == '-' && pCommentEnd[1] == '-' && pCommentEnd[2] == '>') { + break; + } + } + if (pCommentEnd + 2 < pEndOfInput) { + P = pCommentEnd + 3; + } else { + P = pCommentEnd = pEndOfInput; + } + } else { + // Like document type definition, match angle brackets. + pCommentBegin = P; + + int count = 1; + while (*P && count) { + if (*P == '>') { + --count; + } else if (*P == '<') { + ++count; + } + ++P; } - ++P; + if (count) { + pCommentEnd = P; + } else { + pCommentEnd = P - 1; + } } - P -= 3; - node_name = String::utf8(pCommentBegin + 2, (int)(P - pCommentBegin - 2)); - P += 3; + node_name = String::utf8(pCommentBegin, (int)(pCommentEnd - pCommentBegin)); #ifdef DEBUG_XML print_line("XML COMMENT: " + node_name); #endif @@ -178,14 +205,14 @@ void XMLParser::_parse_opening_xml_element() { const char *startName = P; // find end of element - while (*P != '>' && !_is_white_space(*P)) { + while (*P && *P != '>' && !_is_white_space(*P)) { ++P; } const char *endName = P; // find attributes - while (*P != '>') { + while (*P && *P != '>') { if (_is_white_space(*P)) { ++P; } else { @@ -195,10 +222,14 @@ void XMLParser::_parse_opening_xml_element() { // read the attribute names const char *attributeNameBegin = P; - while (!_is_white_space(*P) && *P != '=') { + while (*P && !_is_white_space(*P) && *P != '=') { ++P; } + if (!*P) { + break; + } + const char *attributeNameEnd = P; ++P; @@ -209,7 +240,7 @@ void XMLParser::_parse_opening_xml_element() { } if (!*P) { // malformatted xml file - return; + break; } const char attributeQuoteChar = *P; @@ -221,12 +252,10 @@ void XMLParser::_parse_opening_xml_element() { ++P; } - if (!*P) { // malformatted xml file - return; - } - const char *attributeValueEnd = P; - ++P; + if (*P) { + ++P; + } Attribute attr; attr.name = String::utf8(attributeNameBegin, @@ -258,7 +287,9 @@ void XMLParser::_parse_opening_xml_element() { print_line("XML OPEN: " + node_name); #endif - ++P; + if (*P) { + ++P; + } } void XMLParser::_parse_current_node() { @@ -270,10 +301,6 @@ void XMLParser::_parse_current_node() { ++P; } - if (!*P) { - return; - } - if (P - start > 0) { // we found some text, store it if (_set_text(start, P)) { @@ -281,6 +308,10 @@ void XMLParser::_parse_current_node() { } } + if (!*P) { + return; + } + ++P; // based on current token, parse and report next element @@ -433,7 +464,7 @@ Error XMLParser::open_buffer(const Vector<uint8_t> &p_buffer) { length = p_buffer.size(); data = memnew_arr(char, length + 1); - copymem(data, p_buffer.ptr(), length); + memcpy(data, p_buffer.ptr(), length); data[length] = 0; P = data; return OK; @@ -445,7 +476,7 @@ Error XMLParser::open(const String &p_path) { ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + p_path + "'."); - length = file->get_len(); + length = file->get_length(); ERR_FAIL_COND_V(length < 1, ERR_FILE_CORRUPT); if (data) { diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h index 847edf958d..c323301eac 100644 --- a/core/io/xml_parser.h +++ b/core/io/xml_parser.h @@ -80,7 +80,6 @@ private: Vector<Attribute> attributes; - String _replace_special_characters(const String &origstr); bool _set_text(char *start, char *end); void _parse_closing_xml_element(); void _ignore_definition(); diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp index 4b4a46e198..fb4c76aa7a 100644 --- a/core/io/zip_io.cpp +++ b/core/io/zip_io.cpp @@ -30,8 +30,6 @@ #include "zip_io.h" -#include "core/os/copymem.h" - void *zipio_open(void *data, const char *p_fname, int mode) { FileAccess *&f = *(FileAccess **)data; @@ -70,13 +68,13 @@ long zipio_tell(voidpf opaque, voidpf stream) { long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) { FileAccess *f = *(FileAccess **)opaque; - int pos = offset; + uint64_t 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; + pos = f->get_length() + offset; break; default: break; @@ -103,7 +101,7 @@ int zipio_testerror(voidpf opaque, voidpf stream) { voidpf zipio_alloc(voidpf opaque, uInt items, uInt size) { voidpf ptr = memalloc(items * size); - zeromem(ptr, items * size); + memset(ptr, 0, items * size); return ptr; } |