summaryrefslogtreecommitdiff
path: root/core/io
diff options
context:
space:
mode:
Diffstat (limited to 'core/io')
-rw-r--r--core/io/file_access_encrypted.cpp12
-rw-r--r--core/io/file_access_memory.cpp2
-rw-r--r--core/io/file_access_network.cpp10
-rw-r--r--core/io/http_client.cpp38
-rw-r--r--core/io/http_client.h1
-rw-r--r--core/io/image_loader.cpp80
-rw-r--r--core/io/image_loader.h13
-rw-r--r--core/io/marshalls.cpp177
-rw-r--r--core/io/multiplayer_api.cpp38
-rw-r--r--core/io/packet_peer.cpp8
-rw-r--r--core/io/pck_packer.cpp2
-rw-r--r--core/io/resource_format_binary.cpp4
-rw-r--r--core/io/resource_loader.cpp35
-rw-r--r--core/io/resource_loader.h2
-rw-r--r--core/io/stream_peer.cpp2
-rw-r--r--core/io/stream_peer_ssl.cpp17
-rw-r--r--core/io/stream_peer_ssl.h8
-rw-r--r--core/io/translation_loader_po.cpp40
18 files changed, 319 insertions, 170 deletions
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index 221f457b78..bb7a444ccc 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -89,7 +89,7 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
for (size_t i = 0; i < ds; i += 16) {
- aes256_decrypt_ecb(&ctx, &data[i]);
+ aes256_decrypt_ecb(&ctx, &data.write[i]);
}
aes256_done(&ctx);
@@ -117,7 +117,7 @@ Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base, const Str
key.resize(32);
for (int i = 0; i < 32; i++) {
- key[i] = cs[i];
+ key.write[i] = cs[i];
}
return open_and_parse(p_base, key, p_mode);
@@ -148,7 +148,7 @@ void FileAccessEncrypted::close() {
compressed.resize(len);
zeromem(compressed.ptrw(), len);
for (int i = 0; i < data.size(); i++) {
- compressed[i] = data[i];
+ compressed.write[i] = data[i];
}
aes256_context ctx;
@@ -156,7 +156,7 @@ void FileAccessEncrypted::close() {
for (size_t i = 0; i < len; i += 16) {
- aes256_encrypt_ecb(&ctx, &compressed[i]);
+ aes256_encrypt_ecb(&ctx, &compressed.write[i]);
}
aes256_done(&ctx);
@@ -263,7 +263,7 @@ void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) {
data.resize(pos + p_length);
for (int i = 0; i < p_length; i++) {
- data[pos + i] = p_src[i];
+ data.write[pos + i] = p_src[i];
}
pos += p_length;
}
@@ -280,7 +280,7 @@ void FileAccessEncrypted::store_8(uint8_t p_dest) {
ERR_FAIL_COND(!writing);
if (pos < data.size()) {
- data[pos] = p_dest;
+ data.write[pos] = p_dest;
pos++;
} else if (pos == data.size()) {
data.push_back(p_dest);
diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp
index 1aa1e4a595..c4eb2848b1 100644
--- a/core/io/file_access_memory.cpp
+++ b/core/io/file_access_memory.cpp
@@ -92,7 +92,7 @@ Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) {
Map<String, Vector<uint8_t> >::Element *E = files->find(name);
ERR_FAIL_COND_V(!E, ERR_FILE_NOT_FOUND);
- data = &(E->get()[0]);
+ data = E->get().ptrw();
length = E->get().size();
pos = 0;
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index 21e3a4172b..e0a2dbf507 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -258,8 +258,8 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block)
}
buffer_mutex->lock();
- pages[page].buffer = p_block;
- pages[page].queued = false;
+ pages.write[page].buffer = p_block;
+ pages.write[page].queued = false;
buffer_mutex->unlock();
if (waiting_on_page == page) {
@@ -389,7 +389,7 @@ void FileAccessNetwork::_queue_page(int p_page) const {
br.offset = size_t(p_page) * page_size;
br.size = page_size;
nc->block_requests.push_back(br);
- pages[p_page].queued = true;
+ pages.write[p_page].queued = true;
nc->blockrequest_mutex->unlock();
DEBUG_PRINT("QUEUE PAGE POST");
nc->sem->post();
@@ -433,12 +433,12 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
_queue_page(page + j);
}
- buff = pages[page].buffer.ptrw();
+ buff = pages.write[page].buffer.ptrw();
//queue pages
buffer_mutex->unlock();
}
- buff = pages[page].buffer.ptrw();
+ buff = pages.write[page].buffer.ptrw();
last_page_buff = buff;
last_page = page;
}
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index fcbb22b5de..2425bb6d69 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -279,6 +279,7 @@ void HTTPClient::close() {
chunk_left = 0;
read_until_eof = false;
response_num = 0;
+ handshaking = false;
}
Error HTTPClient::poll() {
@@ -327,16 +328,40 @@ Error HTTPClient::poll() {
} break;
case StreamPeerTCP::STATUS_CONNECTED: {
if (ssl) {
- Ref<StreamPeerSSL> ssl = StreamPeerSSL::create();
- Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, conn_host);
- if (err != OK) {
+ Ref<StreamPeerSSL> ssl;
+ if (!handshaking) {
+ // Connect the StreamPeerSSL and start handshaking
+ ssl = Ref<StreamPeerSSL>(StreamPeerSSL::create());
+ ssl->set_blocking_handshake_enabled(false);
+ Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, conn_host);
+ if (err != OK) {
+ close();
+ status = STATUS_SSL_HANDSHAKE_ERROR;
+ return ERR_CANT_CONNECT;
+ }
+ connection = ssl;
+ handshaking = true;
+ } else {
+ // We are already handshaking, which means we can use your already active SSL connection
+ ssl = static_cast<Ref<StreamPeerSSL> >(connection);
+ ssl->poll(); // Try to finish the handshake
+ }
+
+ if (ssl->get_status() == StreamPeerSSL::STATUS_CONNECTED) {
+ // Handshake has been successfull
+ handshaking = false;
+ status = STATUS_CONNECTED;
+ return OK;
+ } else if (ssl->get_status() != StreamPeerSSL::STATUS_HANDSHAKING) {
+ // Handshake has failed
close();
status = STATUS_SSL_HANDSHAKE_ERROR;
return ERR_CANT_CONNECT;
}
- connection = ssl;
+ // ... we will need to poll more for handshake to finish
+ } else {
+ status = STATUS_CONNECTED;
}
- status = STATUS_CONNECTED;
return OK;
} break;
case StreamPeerTCP::STATUS_ERROR:
@@ -527,7 +552,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
} else {
int rec = 0;
- err = _get_http_data(&chunk[chunk.size() - chunk_left], chunk_left, rec);
+ err = _get_http_data(&chunk.write[chunk.size() - chunk_left], chunk_left, rec);
if (rec == 0) {
break;
}
@@ -669,6 +694,7 @@ HTTPClient::HTTPClient() {
response_num = 0;
ssl = false;
blocking = false;
+ handshaking = false;
read_chunk_size = 4096;
}
diff --git a/core/io/http_client.h b/core/io/http_client.h
index 38ec82ce8c..82b56b01db 100644
--- a/core/io/http_client.h
+++ b/core/io/http_client.h
@@ -165,6 +165,7 @@ private:
bool ssl;
bool ssl_verify_host;
bool blocking;
+ bool handshaking;
Vector<uint8_t> response_str;
diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp
index 8ebd9d6cd9..b8fd13d67c 100644
--- a/core/io/image_loader.cpp
+++ b/core/io/image_loader.cpp
@@ -107,3 +107,83 @@ void ImageLoader::add_image_format_loader(ImageFormatLoader *p_loader) {
ERR_FAIL_COND(loader_count >= MAX_LOADERS);
loader[loader_count++] = p_loader;
}
+
+/////////////////
+
+RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error) {
+
+ FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
+ if (!f) {
+ if (r_error) {
+ *r_error = ERR_CANT_OPEN;
+ }
+ memdelete(f);
+ return RES();
+ }
+
+ uint8_t header[4] = { 0, 0, 0, 0 };
+ f->get_buffer(header, 4);
+
+ bool unrecognized = header[0] != 'G' || header[1] != 'D' || header[2] != 'I' || header[3] != 'M';
+ if (unrecognized) {
+ memdelete(f);
+ if (r_error) {
+ *r_error = ERR_FILE_UNRECOGNIZED;
+ }
+ ERR_FAIL_V(RES());
+ }
+
+ String extension = f->get_pascal_string();
+
+ int idx = -1;
+
+ for (int i = 0; i < ImageLoader::loader_count; i++) {
+ if (ImageLoader::loader[i]->recognize(extension)) {
+ idx = i;
+ break;
+ }
+ }
+
+ if (idx == -1) {
+ memdelete(f);
+ if (r_error) {
+ *r_error = ERR_FILE_UNRECOGNIZED;
+ }
+ ERR_FAIL_V(RES());
+ }
+
+ Ref<Image> image;
+ image.instance();
+
+ Error err = ImageLoader::loader[idx]->load_image(image, f, false, 1.0);
+
+ memdelete(f);
+
+ if (err != OK) {
+ if (r_error) {
+ *r_error = err;
+ }
+ return RES();
+ }
+
+ if (r_error) {
+ *r_error = OK;
+ }
+
+ return image;
+}
+
+void ResourceFormatLoaderImage::get_recognized_extensions(List<String> *p_extensions) const {
+
+ p_extensions->push_back("image");
+}
+
+bool ResourceFormatLoaderImage::handles_type(const String &p_type) const {
+
+ return p_type == "Image";
+}
+
+String ResourceFormatLoaderImage::get_resource_type(const String &p_path) const {
+
+ return p_path.get_extension().to_lower() == "image" ? "Image" : String();
+}
diff --git a/core/io/image_loader.h b/core/io/image_loader.h
index 052a8b8a40..fbb654c326 100644
--- a/core/io/image_loader.h
+++ b/core/io/image_loader.h
@@ -32,9 +32,11 @@
#define IMAGE_LOADER_H
#include "image.h"
+#include "io/resource_loader.h"
#include "list.h"
#include "os/file_access.h"
#include "ustring.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -55,6 +57,7 @@ class ImageLoader;
class ImageFormatLoader {
friend class ImageLoader;
+ friend class ResourceFormatLoaderImage;
protected:
virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess, bool p_force_linear, float p_scale) = 0;
@@ -70,7 +73,7 @@ class ImageLoader {
enum {
MAX_LOADERS = 8
};
-
+ friend class ResourceFormatLoaderImage;
static ImageFormatLoader *loader[MAX_LOADERS];
static int loader_count;
@@ -83,4 +86,12 @@ public:
static void add_image_format_loader(ImageFormatLoader *p_loader);
};
+class ResourceFormatLoaderImage : public ResourceFormatLoader {
+public:
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual bool handles_type(const String &p_type) const;
+ virtual String get_resource_type(const String &p_path) const;
+};
+
#endif
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index 0a3a6c1ba1..e97df0c261 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -32,8 +32,13 @@
#include "os/keyboard.h"
#include "print_string.h"
#include "reference.h"
+#include <limits.h>
#include <stdio.h>
+#define _S(a) ((int32_t)a)
+#define ERR_FAIL_ADD_OF(a, b, err) ERR_FAIL_COND_V(_S(b) < 0 || _S(a) < 0 || _S(a) > INT_MAX - _S(b), err)
+#define ERR_FAIL_MUL_OF(a, b, err) ERR_FAIL_COND_V(_S(a) < 0 || _S(b) <= 0 || _S(a) > INT_MAX / _S(b), err)
+
void EncodedObjectAsID::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_object_id", "id"), &EncodedObjectAsID::set_object_id);
ClassDB::bind_method(D_METHOD("get_object_id"), &EncodedObjectAsID::get_object_id);
@@ -60,23 +65,31 @@ EncodedObjectAsID::EncodedObjectAsID() {
static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r_string) {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- uint32_t strlen = decode_uint32(buf);
+ int32_t strlen = decode_uint32(buf);
+ int32_t pad = 0;
+
+ // Handle padding
+ if (strlen % 4) {
+ pad = 4 - strlen % 4;
+ }
+
buf += 4;
len -= 4;
- ERR_FAIL_COND_V((int)strlen > len, ERR_FILE_EOF);
+
+ // Ensure buffer is big enough
+ ERR_FAIL_ADD_OF(strlen, pad, ERR_FILE_EOF);
+ ERR_FAIL_COND_V(strlen < 0 || strlen + pad > len, ERR_FILE_EOF);
String str;
- str.parse_utf8((const char *)buf, strlen);
+ ERR_FAIL_COND_V(str.parse_utf8((const char *)buf, strlen), ERR_INVALID_DATA);
r_string = str;
- //handle padding
- if (strlen % 4) {
- strlen += 4 - strlen % 4;
- }
+ // Add padding
+ strlen += pad;
+ // Update buffer pos, left data count, and return size
buf += strlen;
len -= strlen;
-
if (r_len) {
(*r_len) += 4 + strlen;
}
@@ -119,14 +132,15 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::INT: {
- ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
if (type & ENCODE_FLAG_64) {
+ ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
int64_t val = decode_uint64(buf);
r_variant = val;
if (r_len)
(*r_len) += 8;
} else {
+ ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t val = decode_uint32(buf);
r_variant = val;
if (r_len)
@@ -136,14 +150,14 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::REAL: {
- ERR_FAIL_COND_V(len < (int)4, ERR_INVALID_DATA);
-
if (type & ENCODE_FLAG_64) {
+ ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
double val = decode_double(buf);
r_variant = val;
if (r_len)
(*r_len) += 8;
} else {
+ ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
float val = decode_float(buf);
r_variant = val;
if (r_len)
@@ -164,7 +178,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
// math types
case Variant::VECTOR2: {
- ERR_FAIL_COND_V(len < (int)4 * 2, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(len < 4 * 2, ERR_INVALID_DATA);
Vector2 val;
val.x = decode_float(&buf[0]);
val.y = decode_float(&buf[4]);
@@ -176,7 +190,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break; // 5
case Variant::RECT2: {
- ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA);
Rect2 val;
val.position.x = decode_float(&buf[0]);
val.position.y = decode_float(&buf[4]);
@@ -190,7 +204,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::VECTOR3: {
- ERR_FAIL_COND_V(len < (int)4 * 3, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(len < 4 * 3, ERR_INVALID_DATA);
Vector3 val;
val.x = decode_float(&buf[0]);
val.y = decode_float(&buf[4]);
@@ -203,7 +217,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::TRANSFORM2D: {
- ERR_FAIL_COND_V(len < (int)4 * 6, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(len < 4 * 6, ERR_INVALID_DATA);
Transform2D val;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
@@ -220,7 +234,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::PLANE: {
- ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA);
Plane val;
val.normal.x = decode_float(&buf[0]);
val.normal.y = decode_float(&buf[4]);
@@ -234,7 +248,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::QUAT: {
- ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA);
Quat val;
val.x = decode_float(&buf[0]);
val.y = decode_float(&buf[4]);
@@ -248,7 +262,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::AABB: {
- ERR_FAIL_COND_V(len < (int)4 * 6, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(len < 4 * 6, ERR_INVALID_DATA);
AABB val;
val.position.x = decode_float(&buf[0]);
val.position.y = decode_float(&buf[4]);
@@ -264,7 +278,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::BASIS: {
- ERR_FAIL_COND_V(len < (int)4 * 9, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(len < 4 * 9, ERR_INVALID_DATA);
Basis val;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
@@ -281,7 +295,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::TRANSFORM: {
- ERR_FAIL_COND_V(len < (int)4 * 12, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(len < 4 * 12, ERR_INVALID_DATA);
Transform val;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
@@ -303,7 +317,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
// misc types
case Variant::COLOR: {
- ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA);
Color val;
val.r = decode_float(&buf[0]);
val.g = decode_float(&buf[4]);
@@ -318,7 +332,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
case Variant::NODE_PATH: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- uint32_t strlen = decode_uint32(buf);
+ int32_t strlen = decode_uint32(buf);
if (strlen & 0x80000000) {
//new format
@@ -343,31 +357,15 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
for (uint32_t i = 0; i < total; i++) {
- ERR_FAIL_COND_V((int)len < 4, ERR_INVALID_DATA);
- strlen = decode_uint32(buf);
-
- int pad = 0;
-
- if (strlen % 4)
- pad += 4 - strlen % 4;
-
- buf += 4;
- len -= 4;
- ERR_FAIL_COND_V((int)strlen + pad > len, ERR_INVALID_DATA);
-
String str;
- str.parse_utf8((const char *)buf, strlen);
+ Error err = _decode_string(buf, len, r_len, str);
+ if (err)
+ return err;
if (i < namecount)
names.push_back(str);
else
subnames.push_back(str);
-
- buf += strlen + pad;
- len -= strlen + pad;
-
- if (r_len)
- (*r_len) += 4 + strlen + pad;
}
r_variant = NodePath(names, subnames, flags & 1);
@@ -375,17 +373,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} else {
//old format, just a string
- buf += 4;
- len -= 4;
- ERR_FAIL_COND_V((int)strlen > len, ERR_INVALID_DATA);
-
- String str;
- str.parse_utf8((const char *)buf, strlen);
-
- r_variant = NodePath(str);
-
- if (r_len)
- (*r_len) += 4 + strlen;
+ ERR_FAIL_V(ERR_INVALID_DATA);
}
} break;
@@ -402,6 +390,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
if (type & ENCODE_FLAG_OBJECT_AS_ID) {
//this _is_ allowed
+ ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
ObjectID val = decode_uint64(buf);
if (r_len)
(*r_len) += 8;
@@ -475,7 +464,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
case Variant::DICTIONARY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- uint32_t count = decode_uint32(buf);
+ int32_t count = decode_uint32(buf);
// bool shared = count&0x80000000;
count &= 0x7FFFFFFF;
@@ -488,7 +477,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
Dictionary d;
- for (uint32_t i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++) {
Variant key, value;
@@ -520,7 +509,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
case Variant::ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- uint32_t count = decode_uint32(buf);
+ int32_t count = decode_uint32(buf);
// bool shared = count&0x80000000;
count &= 0x7FFFFFFF;
@@ -533,7 +522,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
Array varr;
- for (uint32_t i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++) {
int used = 0;
Variant v;
@@ -555,17 +544,17 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
case Variant::POOL_BYTE_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- uint32_t count = decode_uint32(buf);
+ int32_t count = decode_uint32(buf);
buf += 4;
len -= 4;
- ERR_FAIL_COND_V((int)count > len, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(count < 0 || count > len, ERR_INVALID_DATA);
PoolVector<uint8_t> data;
if (count) {
data.resize(count);
PoolVector<uint8_t>::Write w = data.write();
- for (uint32_t i = 0; i < count; i++) {
+ for (int32_t i = 0; i < count; i++) {
w[i] = buf[i];
}
@@ -585,10 +574,11 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
case Variant::POOL_INT_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- uint32_t count = decode_uint32(buf);
+ int32_t count = decode_uint32(buf);
buf += 4;
len -= 4;
- ERR_FAIL_COND_V((int)count * 4 > len, ERR_INVALID_DATA);
+ ERR_FAIL_MUL_OF(count, 4, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(count < 0 || count * 4 > len, ERR_INVALID_DATA);
PoolVector<int> data;
@@ -596,7 +586,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
//const int*rbuf=(const int*)buf;
data.resize(count);
PoolVector<int>::Write w = data.write();
- for (uint32_t i = 0; i < count; i++) {
+ for (int32_t i = 0; i < count; i++) {
w[i] = decode_uint32(&buf[i * 4]);
}
@@ -612,10 +602,11 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
case Variant::POOL_REAL_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- uint32_t count = decode_uint32(buf);
+ int32_t count = decode_uint32(buf);
buf += 4;
len -= 4;
- ERR_FAIL_COND_V((int)count * 4 > len, ERR_INVALID_DATA);
+ ERR_FAIL_MUL_OF(count, 4, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(count < 0 || count * 4 > len, ERR_INVALID_DATA);
PoolVector<float> data;
@@ -623,7 +614,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
//const float*rbuf=(const float*)buf;
data.resize(count);
PoolVector<float>::Write w = data.write();
- for (uint32_t i = 0; i < count; i++) {
+ for (int32_t i = 0; i < count; i++) {
w[i] = decode_float(&buf[i * 4]);
}
@@ -640,7 +631,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
case Variant::POOL_STRING_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- uint32_t count = decode_uint32(buf);
+ int32_t count = decode_uint32(buf);
PoolVector<String> strings;
buf += 4;
@@ -650,35 +641,14 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
(*r_len) += 4;
//printf("string count: %i\n",count);
- for (int i = 0; i < (int)count; i++) {
+ for (int32_t i = 0; i < count; i++) {
- ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- uint32_t strlen = decode_uint32(buf);
-
- buf += 4;
- len -= 4;
- ERR_FAIL_COND_V((int)strlen > len, ERR_INVALID_DATA);
-
- //printf("loaded string: %s\n",(const char*)buf);
String str;
- str.parse_utf8((const char *)buf, strlen);
+ Error err = _decode_string(buf, len, r_len, str);
+ if (err)
+ return err;
strings.push_back(str);
-
- buf += strlen;
- len -= strlen;
-
- if (r_len)
- (*r_len) += 4 + strlen;
-
- if (strlen % 4) {
- int pad = 4 - (strlen % 4);
- buf += pad;
- len -= pad;
- if (r_len) {
- (*r_len) += pad;
- }
- }
}
r_variant = strings;
@@ -687,11 +657,12 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
case Variant::POOL_VECTOR2_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- uint32_t count = decode_uint32(buf);
+ int32_t count = decode_uint32(buf);
buf += 4;
len -= 4;
- ERR_FAIL_COND_V((int)count * 4 * 2 > len, ERR_INVALID_DATA);
+ ERR_FAIL_MUL_OF(count, 4 * 2, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(count < 0 || count * 4 * 2 > len, ERR_INVALID_DATA);
PoolVector<Vector2> varray;
if (r_len) {
@@ -702,7 +673,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
varray.resize(count);
PoolVector<Vector2>::Write w = varray.write();
- for (int i = 0; i < (int)count; i++) {
+ for (int32_t i = 0; i < count; i++) {
w[i].x = decode_float(buf + i * 4 * 2 + 4 * 0);
w[i].y = decode_float(buf + i * 4 * 2 + 4 * 1);
@@ -722,11 +693,13 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
case Variant::POOL_VECTOR3_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- uint32_t count = decode_uint32(buf);
+ int32_t count = decode_uint32(buf);
buf += 4;
len -= 4;
- ERR_FAIL_COND_V((int)count * 4 * 3 > len, ERR_INVALID_DATA);
+ ERR_FAIL_MUL_OF(count, 4 * 3, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(count < 0 || count * 4 * 3 > len, ERR_INVALID_DATA);
+
PoolVector<Vector3> varray;
if (r_len) {
@@ -737,7 +710,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
varray.resize(count);
PoolVector<Vector3>::Write w = varray.write();
- for (int i = 0; i < (int)count; i++) {
+ for (int32_t i = 0; i < count; i++) {
w[i].x = decode_float(buf + i * 4 * 3 + 4 * 0);
w[i].y = decode_float(buf + i * 4 * 3 + 4 * 1);
@@ -758,11 +731,13 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
case Variant::POOL_COLOR_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- uint32_t count = decode_uint32(buf);
+ int32_t count = decode_uint32(buf);
buf += 4;
len -= 4;
- ERR_FAIL_COND_V((int)count * 4 * 4 > len, ERR_INVALID_DATA);
+ ERR_FAIL_MUL_OF(count, 4 * 4, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(count < 0 || count * 4 * 4 > len, ERR_INVALID_DATA);
+
PoolVector<Color> carray;
if (r_len) {
@@ -773,7 +748,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
carray.resize(count);
PoolVector<Color>::Write w = carray.write();
- for (int i = 0; i < (int)count; i++) {
+ for (int32_t i = 0; i < count; i++) {
w[i].r = decode_float(buf + i * 4 * 4 + 4 * 0);
w[i].g = decode_float(buf + i * 4 * 4 + 4 * 1);
@@ -1323,7 +1298,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
while (r_len % 4) {
r_len++; //pad
if (buf)
- buf++;
+ *(buf++) = 0;
}
}
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index ffd3ecaed0..8e67f1c97a 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -282,10 +282,10 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
ERR_FAIL_COND(p_offset >= p_packet_len);
int vlen;
- Error err = decode_variant(args[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen);
+ Error err = decode_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen);
ERR_FAIL_COND(err != OK);
//args[i]=p_packet[3+i];
- argp[i] = &args[i];
+ argp.write[i] = &args[i];
p_offset += vlen;
}
@@ -354,8 +354,8 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
Vector<uint8_t> packet;
packet.resize(1 + len);
- packet[0] = NETWORK_COMMAND_CONFIRM_PATH;
- encode_cstring(pname.get_data(), &packet[1]);
+ packet.write[0] = NETWORK_COMMAND_CONFIRM_PATH;
+ encode_cstring(pname.get_data(), &packet.write[1]);
network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
network_peer->set_target_peer(p_from);
@@ -415,9 +415,9 @@ bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int
Vector<uint8_t> packet;
packet.resize(1 + 4 + len);
- packet[0] = NETWORK_COMMAND_SIMPLIFY_PATH;
- encode_uint32(psc->id, &packet[1]);
- encode_cstring(pname.get_data(), &packet[5]);
+ packet.write[0] = NETWORK_COMMAND_SIMPLIFY_PATH;
+ encode_uint32(psc->id, &packet.write[1]);
+ encode_cstring(pname.get_data(), &packet.write[5]);
network_peer->set_target_peer(E->get()); //to all of you
network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
@@ -482,19 +482,19 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
//encode type
MAKE_ROOM(1);
- packet_cache[0] = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL;
+ packet_cache.write[0] = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL;
ofs += 1;
//encode ID
MAKE_ROOM(ofs + 4);
- encode_uint32(psc->id, &(packet_cache[ofs]));
+ encode_uint32(psc->id, &(packet_cache.write[ofs]));
ofs += 4;
//encode function name
CharString name = String(p_name).utf8();
int len = encode_cstring(name.get_data(), NULL);
MAKE_ROOM(ofs + len);
- encode_cstring(name.get_data(), &(packet_cache[ofs]));
+ encode_cstring(name.get_data(), &(packet_cache.write[ofs]));
ofs += len;
if (p_set) {
@@ -502,19 +502,19 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
Error err = encode_variant(*p_arg[0], NULL, len);
ERR_FAIL_COND(err != OK);
MAKE_ROOM(ofs + len);
- encode_variant(*p_arg[0], &(packet_cache[ofs]), len);
+ encode_variant(*p_arg[0], &(packet_cache.write[ofs]), len);
ofs += len;
} else {
//call arguments
MAKE_ROOM(ofs + 1);
- packet_cache[ofs] = p_argcount;
+ packet_cache.write[ofs] = p_argcount;
ofs += 1;
for (int i = 0; i < p_argcount; i++) {
Error err = encode_variant(*p_arg[i], NULL, len);
ERR_FAIL_COND(err != OK);
MAKE_ROOM(ofs + len);
- encode_variant(*p_arg[i], &(packet_cache[ofs]), len);
+ encode_variant(*p_arg[i], &(packet_cache.write[ofs]), len);
ofs += len;
}
}
@@ -537,7 +537,7 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
CharString pname = String(from_path).utf8();
int path_len = encode_cstring(pname.get_data(), NULL);
MAKE_ROOM(ofs + path_len);
- encode_cstring(pname.get_data(), &(packet_cache[ofs]));
+ encode_cstring(pname.get_data(), &(packet_cache.write[ofs]));
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
@@ -554,11 +554,11 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
if (F->get() == true) {
//this one confirmed path, so use id
- encode_uint32(psc->id, &(packet_cache[1]));
+ encode_uint32(psc->id, &(packet_cache.write[1]));
network_peer->put_packet(packet_cache.ptr(), ofs);
} else {
//this one did not confirm path yet, so use entire path (sorry!)
- encode_uint32(0x80000000 | ofs, &(packet_cache[1])); //offset to path and flag
+ encode_uint32(0x80000000 | ofs, &(packet_cache.write[1])); //offset to path and flag
network_peer->put_packet(packet_cache.ptr(), ofs + path_len);
}
}
@@ -712,8 +712,8 @@ Error MultiplayerAPI::send_bytes(PoolVector<uint8_t> p_data, int p_to, Networked
MAKE_ROOM(p_data.size() + 1);
PoolVector<uint8_t>::Read r = p_data.read();
- packet_cache[0] = NETWORK_COMMAND_RAW;
- memcpy(&packet_cache[1], &r[0], p_data.size());
+ packet_cache.write[0] = NETWORK_COMMAND_RAW;
+ memcpy(&packet_cache.write[1], &r[0], p_data.size());
network_peer->set_target_peer(p_to);
network_peer->set_transfer_mode(p_mode);
@@ -773,7 +773,7 @@ Vector<int> MultiplayerAPI::get_network_connected_peers() const {
void MultiplayerAPI::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_root_node", "node"), &MultiplayerAPI::set_root_node);
- ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id"), &MultiplayerAPI::send_bytes, DEFVAL(NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE));
+ ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id", "mode"), &MultiplayerAPI::send_bytes, DEFVAL(NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE));
ClassDB::bind_method(D_METHOD("has_network_peer"), &MultiplayerAPI::has_network_peer);
ClassDB::bind_method(D_METHOD("get_network_peer"), &MultiplayerAPI::get_network_peer);
ClassDB::bind_method(D_METHOD("get_network_unique_id"), &MultiplayerAPI::get_network_unique_id);
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index b777a9f960..dc4997dfc2 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -173,7 +173,7 @@ Error PacketPeerStream::_poll_buffer() const {
int read = 0;
ERR_FAIL_COND_V(input_buffer.size() < ring_buffer.space_left(), ERR_UNAVAILABLE);
- Error err = peer->get_partial_data(&input_buffer[0], ring_buffer.space_left(), read);
+ Error err = peer->get_partial_data(input_buffer.ptrw(), ring_buffer.space_left(), read);
if (err)
return err;
if (read == 0)
@@ -226,7 +226,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size)
ERR_FAIL_COND_V(input_buffer.size() < len, ERR_UNAVAILABLE);
ring_buffer.read(lbuf, 4); //get rid of first 4 bytes
- ring_buffer.read(&input_buffer[0], len); // read packet
+ ring_buffer.read(input_buffer.ptrw(), len); // read packet
*r_buffer = &input_buffer[0];
r_buffer_size = len;
@@ -247,8 +247,8 @@ Error PacketPeerStream::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
ERR_FAIL_COND_V(p_buffer_size < 0, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_buffer_size + 4 > output_buffer.size(), ERR_INVALID_PARAMETER);
- encode_uint32(p_buffer_size, &output_buffer[0]);
- uint8_t *dst = &output_buffer[4];
+ encode_uint32(p_buffer_size, output_buffer.ptrw());
+ uint8_t *dst = &output_buffer.write[4];
for (int i = 0; i < p_buffer_size; i++)
dst[i] = p_buffer[i];
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index b6377662de..2fd73db27d 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -120,7 +120,7 @@ Error PCKPacker::flush(bool p_verbose) {
for (int i = 0; i < files.size(); i++) {
file->store_pascal_string(files[i].path);
- files[i].offset_offset = file->get_position();
+ files.write[i].offset_offset = file->get_position();
file->store_64(0); // offset
file->store_64(files[i].size); // size
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 0c626c197b..02c2c6ce1a 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -894,7 +894,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
for (uint32_t i = 0; i < string_table_size; i++) {
StringName s = get_unicode_string();
- string_map[i] = s;
+ string_map.write[i] = s;
}
print_bl("strings: " + itos(string_table_size));
@@ -1834,7 +1834,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
save_order.resize(external_resources.size());
for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) {
- save_order[E->get()] = E->key();
+ save_order.write[E->get()] = E->key();
}
for (int i = 0; i < save_order.size(); i++) {
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 1351030d1e..ab2d18eb1b 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -123,6 +123,9 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const Stri
return ril;
}
+bool ResourceFormatLoader::exists(const String &p_path) const {
+ return FileAccess::exists(p_path); //by default just check file
+}
RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error) {
String path = p_path;
@@ -239,6 +242,36 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
return res;
}
+bool ResourceLoader::exists(const String &p_path, const String &p_type_hint) {
+
+ String local_path;
+ if (p_path.is_rel_path())
+ local_path = "res://" + p_path;
+ else
+ local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+
+ if (ResourceCache::has(local_path)) {
+
+ return false; //if cached, it probably exists i guess
+ }
+
+ bool xl_remapped = false;
+ String path = _path_remap(local_path, &xl_remapped);
+
+ // Try all loaders and pick the first match for the type hint
+ for (int i = 0; i < loader_count; i++) {
+
+ if (!loader[i]->recognize_path(path, p_type_hint)) {
+ continue;
+ }
+
+ if (loader[i]->exists(path))
+ return true;
+ }
+
+ return false;
+}
+
Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
if (r_error)
@@ -556,7 +589,7 @@ void ResourceLoader::load_translation_remaps() {
Vector<String> lang_remaps;
lang_remaps.resize(langs.size());
for (int i = 0; i < langs.size(); i++) {
- lang_remaps[i] = langs[i];
+ lang_remaps.write[i] = langs[i];
}
translation_remaps[String(E->get())] = lang_remaps;
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 9be82abb42..f78464ef0c 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -60,6 +60,7 @@ class ResourceFormatLoader {
public:
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual bool exists(const String &p_path) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const;
@@ -106,6 +107,7 @@ class ResourceLoader {
public:
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
static RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
+ static bool exists(const String &p_path, const String &p_type_hint = "");
static void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions);
static void add_resource_format_loader(ResourceFormatLoader *p_format_loader, bool p_at_front = false);
diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp
index 927b9f6366..3e0ee088c2 100644
--- a/core/io/stream_peer.cpp
+++ b/core/io/stream_peer.cpp
@@ -331,7 +331,7 @@ String StreamPeer::get_string(int p_bytes) {
ERR_FAIL_COND_V(err != OK, String());
err = get_data((uint8_t *)&buf[0], p_bytes);
ERR_FAIL_COND_V(err != OK, String());
- buf[p_bytes] = 0;
+ buf.write[p_bytes] = 0;
return buf.ptr();
}
String StreamPeer::get_utf8_string(int p_bytes) {
diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp
index 012ba78c6d..e7e9662d24 100644
--- a/core/io/stream_peer_ssl.cpp
+++ b/core/io/stream_peer_ssl.cpp
@@ -52,6 +52,14 @@ bool StreamPeerSSL::is_available() {
return available;
}
+void StreamPeerSSL::set_blocking_handshake_enabled(bool p_enabled) {
+ blocking_handshake = p_enabled;
+}
+
+bool StreamPeerSSL::is_blocking_handshake_enabled() const {
+ return blocking_handshake;
+}
+
PoolByteArray StreamPeerSSL::get_project_cert_array() {
PoolByteArray out;
@@ -84,16 +92,21 @@ PoolByteArray StreamPeerSSL::get_project_cert_array() {
void StreamPeerSSL::_bind_methods() {
ClassDB::bind_method(D_METHOD("poll"), &StreamPeerSSL::poll);
- ClassDB::bind_method(D_METHOD("accept_stream", "stream"), &StreamPeerSSL::accept_stream);
+ ClassDB::bind_method(D_METHOD("accept_stream", "base"), &StreamPeerSSL::accept_stream);
ClassDB::bind_method(D_METHOD("connect_to_stream", "stream", "validate_certs", "for_hostname"), &StreamPeerSSL::connect_to_stream, DEFVAL(false), DEFVAL(String()));
ClassDB::bind_method(D_METHOD("get_status"), &StreamPeerSSL::get_status);
ClassDB::bind_method(D_METHOD("disconnect_from_stream"), &StreamPeerSSL::disconnect_from_stream);
+ ClassDB::bind_method(D_METHOD("set_blocking_handshake_enabled", "enabled"), &StreamPeerSSL::set_blocking_handshake_enabled);
+ ClassDB::bind_method(D_METHOD("is_blocking_handshake_enabled"), &StreamPeerSSL::is_blocking_handshake_enabled);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "blocking_handshake"), "set_blocking_handshake_enabled", "is_blocking_handshake_enabled");
BIND_ENUM_CONSTANT(STATUS_DISCONNECTED);
BIND_ENUM_CONSTANT(STATUS_CONNECTED);
- BIND_ENUM_CONSTANT(STATUS_ERROR_NO_CERTIFICATE);
+ BIND_ENUM_CONSTANT(STATUS_ERROR);
BIND_ENUM_CONSTANT(STATUS_ERROR_HOSTNAME_MISMATCH);
}
StreamPeerSSL::StreamPeerSSL() {
+ blocking_handshake = true;
}
diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h
index 77301a7c87..870704e875 100644
--- a/core/io/stream_peer_ssl.h
+++ b/core/io/stream_peer_ssl.h
@@ -49,14 +49,20 @@ protected:
friend class Main;
static bool initialize_certs;
+ bool blocking_handshake;
+
public:
enum Status {
STATUS_DISCONNECTED,
+ STATUS_HANDSHAKING,
STATUS_CONNECTED,
- STATUS_ERROR_NO_CERTIFICATE,
+ STATUS_ERROR,
STATUS_ERROR_HOSTNAME_MISMATCH
};
+ void set_blocking_handshake_enabled(bool p_enabled);
+ bool is_blocking_handshake_enabled() const;
+
virtual void poll() = 0;
virtual Error accept_stream(Ref<StreamPeer> p_base) = 0;
virtual Error connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs = false, const String &p_for_hostname = String()) = 0;
diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp
index 16d5e3c282..85c1fc5ddf 100644
--- a/core/io/translation_loader_po.cpp
+++ b/core/io/translation_loader_po.cpp
@@ -54,32 +54,25 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
int line = 1;
bool skip_this = false;
bool skip_next = false;
+ bool is_eof = false;
- while (true) {
+ while (!is_eof) {
- String l = f->get_line();
+ String l = f->get_line().strip_edges();
+ is_eof = f->eof_reached();
- if (f->eof_reached()) {
+ // If we reached last line and it's not a content line, break, otherwise let processing that last loop
+ if (is_eof && l.empty()) {
- if (status == STATUS_READING_STRING) {
-
- if (msg_id != "") {
- if (!skip_this)
- translation->add_message(msg_id, msg_str);
- } else if (config == "")
- config = msg_str;
- break;
-
- } else if (status == STATUS_NONE)
+ if (status == STATUS_READING_ID) {
+ memdelete(f);
+ ERR_EXPLAIN(p_path + ":" + itos(line) + " Unexpected EOF while reading 'msgid' at file: ");
+ ERR_FAIL_V(RES());
+ } else {
break;
-
- memdelete(f);
- ERR_EXPLAIN(p_path + ":" + itos(line) + " Unexpected EOF while reading 'msgid' at file: ");
- ERR_FAIL_V(RES());
+ }
}
- l = l.strip_edges();
-
if (l.begins_with("msgid")) {
if (status == STATUS_READING_ID) {
@@ -160,6 +153,15 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
f->close();
memdelete(f);
+ if (status == STATUS_READING_STRING) {
+
+ if (msg_id != "") {
+ if (!skip_this)
+ translation->add_message(msg_id, msg_str);
+ } else if (config == "")
+ config = msg_str;
+ }
+
if (config == "") {
ERR_EXPLAIN("No config found in file: " + p_path);
ERR_FAIL_V(RES());