diff options
Diffstat (limited to 'core')
34 files changed, 634 insertions, 282 deletions
diff --git a/core/SCsub b/core/SCsub index cbed2e4f35..caae3a1c9b 100644 --- a/core/SCsub +++ b/core/SCsub @@ -2,66 +2,66 @@ Import('env') -env.core_sources=[] +env.core_sources = [] -gd_call="" -gd_inc="" +gd_call = "" +gd_inc = "" for x in env.global_defaults: - env.core_sources.append("#platform/"+x+"/globals/global_defaults.cpp") - gd_inc+='#include "platform/'+x+'/globals/global_defaults.h"\n' - gd_call+="\tregister_"+x+"_global_defaults();\n" + env.core_sources.append("#platform/" + x + "/globals/global_defaults.cpp") + gd_inc += '#include "platform/' + x + '/globals/global_defaults.h"\n' + gd_call += "\tregister_" + x + "_global_defaults();\n" -gd_cpp='#include "globals.h"\n' -gd_cpp+=gd_inc -gd_cpp+="void Globals::register_global_defaults() {\n"+gd_call+"\n}\n" +gd_cpp = '#include "globals.h"\n' +gd_cpp += gd_inc +gd_cpp += "void Globals::register_global_defaults() {\n" + gd_call + "\n}\n" -f = open("global_defaults.cpp","wb") +f = open("global_defaults.cpp", "wb") f.write(gd_cpp) f.close() import os txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0" if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ): - e=os.environ["SCRIPT_AES256_ENCRYPTION_KEY"] - txt = "" - ec_valid=True - if (len(e)!=64): - ec_valid=False - else: - - for i in range(len(e)>>1): - if (i>0): - txt+="," - txts="0x"+e[i*2:i*2+2] - try: - int(txts,16) - except: - ec_valid=False - txt+=txts - if (not ec_valid): - txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0" - print("Invalid AES256 encryption key, not 64 bits hex: "+e) + e = os.environ["SCRIPT_AES256_ENCRYPTION_KEY"] + txt = "" + ec_valid = True + if (len(e) != 64): + ec_valid = False + else: + + for i in range(len(e) >> 1): + if (i > 0): + txt += "," + txts = "0x" + e[i * 2:i * 2 + 2] + try: + int(txts, 16) + except: + ec_valid = False + txt += txts + if (not ec_valid): + txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0" + print("Invalid AES256 encryption key, not 64 bits hex: " + e) f = open("script_encryption_key.cpp", "wb") f.write("#include \"globals.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n") f.close() -env.add_source_files(env.core_sources,"*.cpp") +env.add_source_files(env.core_sources, "*.cpp") Export('env') import make_binders -env.Command(['method_bind.inc','method_bind_ext.inc'], 'make_binders.py', make_binders.run) +env.Command(['method_bind.inc', 'method_bind_ext.inc'], 'make_binders.py', make_binders.run) -SConscript('os/SCsub'); -SConscript('math/SCsub'); -SConscript('io/SCsub'); -SConscript('bind/SCsub'); +SConscript('os/SCsub') +SConscript('math/SCsub') +SConscript('io/SCsub') +SConscript('bind/SCsub') -lib = env.Library("core",env.core_sources) +lib = env.Library("core", env.core_sources) env.Prepend(LIBS=[lib]) diff --git a/core/bind/SCsub b/core/bind/SCsub index c2731d60e6..4efc902717 100644 --- a/core/bind/SCsub +++ b/core/bind/SCsub @@ -2,6 +2,6 @@ Import('env') -env.add_source_files(env.core_sources,"*.cpp") +env.add_source_files(env.core_sources, "*.cpp") Export('env') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 4e815d044d..df49ecebcf 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -480,9 +480,9 @@ void _OS::set_use_vsync(bool p_enable) { OS::get_singleton()->set_use_vsync(p_enable); } -bool _OS::is_vsnc_enabled() const { +bool _OS::is_vsync_enabled() const { - return OS::get_singleton()->is_vsnc_enabled(); + return OS::get_singleton()->is_vsync_enabled(); } @@ -1172,7 +1172,7 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_thread_name","name"),&_OS::set_thread_name); ObjectTypeDB::bind_method(_MD("set_use_vsync","enable"),&_OS::set_use_vsync); - ObjectTypeDB::bind_method(_MD("is_vsnc_enabled"),&_OS::is_vsnc_enabled); + ObjectTypeDB::bind_method(_MD("is_vsync_enabled"),&_OS::is_vsync_enabled); ObjectTypeDB::bind_method(_MD("get_engine_version"),&_OS::get_engine_version); @@ -2043,6 +2043,13 @@ _Directory::~_Directory() { memdelete(d); } +_Marshalls* _Marshalls::singleton=NULL; + +_Marshalls *_Marshalls::get_singleton() +{ + return singleton; +} + String _Marshalls::variant_to_base64(const Variant& p_var) { int len; diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 14203ae863..2fb7f93cef 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -318,7 +318,7 @@ public: Error set_thread_name(const String& p_name); void set_use_vsync(bool p_enable); - bool is_vsnc_enabled() const; + bool is_vsync_enabled() const; Dictionary get_engine_version() const; @@ -503,6 +503,8 @@ class _Marshalls : public Reference { OBJ_TYPE(_Marshalls,Reference); + static _Marshalls* singleton; + protected: static void _bind_methods(); @@ -510,6 +512,8 @@ protected: public: + static _Marshalls* get_singleton(); + String variant_to_base64(const Variant& p_var); Variant base64_to_variant(const String& p_str); @@ -519,7 +523,8 @@ public: String utf8_to_base64(const String& p_str); String base64_to_utf8(const String& p_str); - _Marshalls() {}; + _Marshalls() { singleton = this; } + ~_Marshalls() { singleton = NULL; } }; diff --git a/core/error_list.h b/core/error_list.h index cb531f527f..154af679fc 100644 --- a/core/error_list.h +++ b/core/error_list.h @@ -57,33 +57,33 @@ enum Error { ERR_FILE_MISSING_DEPENDENCIES, ERR_FILE_EOF, ERR_CANT_OPEN, ///< Can't open a resource/socket/file - ERR_CANT_CREATE, - ERROR_QUERY_FAILED, // (20) + ERR_CANT_CREATE, // (20) + ERROR_QUERY_FAILED, ERR_ALREADY_IN_USE, ERR_LOCKED, ///< resource is locked ERR_TIMEOUT, - ERR_CANT_CONNECT, - ERR_CANT_RESOLVE, // (25) + ERR_CANT_CONNECT, // (25) + ERR_CANT_RESOLVE, ERR_CONNECTION_ERROR, ERR_CANT_AQUIRE_RESOURCE, ERR_CANT_FORK, - ERR_INVALID_DATA, ///< Data passed is invalid - ERR_INVALID_PARAMETER, ///< Parameter passed is invalid (30) + ERR_INVALID_DATA, ///< Data passed is invalid (30) + ERR_INVALID_PARAMETER, ///< Parameter passed is invalid ERR_ALREADY_EXISTS, ///< When adding, item already exists ERR_DOES_NOT_EXIST, ///< When retrieving/erasing, it item does not exist ERR_DATABASE_CANT_READ, ///< database is full - ERR_DATABASE_CANT_WRITE, ///< database is full - ERR_COMPILATION_FAILED, // (35) + ERR_DATABASE_CANT_WRITE, ///< database is full (35) + ERR_COMPILATION_FAILED, ERR_METHOD_NOT_FOUND, ERR_LINK_FAILED, ERR_SCRIPT_FAILED, - ERR_CYCLIC_LINK, - ERR_INVALID_DECLARATION, // (40) + ERR_CYCLIC_LINK, // (40) + ERR_INVALID_DECLARATION, ERR_DUPLICATE_SYMBOL, ERR_PARSE_ERROR, ERR_BUSY, - ERR_SKIP, - ERR_HELP, ///< user requested help!! (45) + ERR_SKIP, // (45) + ERR_HELP, ///< user requested help!! ERR_BUG, ///< a bug in the software certainly happened, due to a double check failing or unexpected behavior. ERR_PRINTER_ON_FIRE, /// the parallel port printer is engulfed in flames ERR_OMFG_THIS_IS_VERY_VERY_BAD, ///< shit happens, has never been used, though diff --git a/core/io/SCsub b/core/io/SCsub index 48cc9a5275..6789aa8bc6 100644 --- a/core/io/SCsub +++ b/core/io/SCsub @@ -2,8 +2,8 @@ Import('env') -env.add_source_files(env.core_sources,"*.cpp") -env.add_source_files(env.core_sources,"*.c") -#env.core_sources.append("io/fastlz.c") +env.add_source_files(env.core_sources, "*.cpp") +env.add_source_files(env.core_sources, "*.c") +# env.core_sources.append("io/fastlz.c") Export('env') diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 2a831dd992..e3289b452c 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -29,8 +29,9 @@ #include "http_client.h" #include "io/stream_peer_ssl.h" +VARIANT_ENUM_CAST(IP_Address::AddrType); -Error HTTPClient::connect(const String &p_host, int p_port, bool p_ssl,bool p_verify_host){ +Error HTTPClient::connect(const String &p_host, int p_port, bool p_ssl,bool p_verify_host, IP_Address::AddrType p_addr_type){ close(); conn_port=p_port; @@ -62,7 +63,7 @@ Error HTTPClient::connect(const String &p_host, int p_port, bool p_ssl,bool p_ve status=STATUS_CONNECTING; } else { //is hostname - resolving=IP::get_singleton()->resolve_hostname_queue_item(conn_host); + resolving=IP::get_singleton()->resolve_hostname_queue_item(conn_host, p_addr_type); status=STATUS_RESOLVING; } @@ -635,7 +636,7 @@ Error HTTPClient::_get_http_data(uint8_t* p_buffer, int p_bytes,int &r_received) void HTTPClient::_bind_methods() { - ObjectTypeDB::bind_method(_MD("connect:Error","host","port","use_ssl","verify_host"),&HTTPClient::connect,DEFVAL(false),DEFVAL(true)); + ObjectTypeDB::bind_method(_MD("connect:Error","host","port","use_ssl","verify_host"),&HTTPClient::connect,DEFVAL(false),DEFVAL(true),DEFVAL(IP_Address::TYPE_ANY)); ObjectTypeDB::bind_method(_MD("set_connection","connection:StreamPeer"),&HTTPClient::set_connection); ObjectTypeDB::bind_method(_MD("get_connection:StreamPeer"),&HTTPClient::get_connection); ObjectTypeDB::bind_method(_MD("request_raw","method","url","headers","body"),&HTTPClient::request_raw); diff --git a/core/io/http_client.h b/core/io/http_client.h index 32d2e72101..ba464c34c7 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -165,7 +165,7 @@ public: //Error connect_and_get(const String& p_url,bool p_verify_host=true); //connects to a full url and perform request - Error connect(const String &p_host,int p_port,bool p_ssl=false,bool p_verify_host=true); + Error connect(const String &p_host,int p_port,bool p_ssl=false,bool p_verify_host=true, IP_Address::AddrType p_addr_type = IP_Address::TYPE_ANY); void set_connection(const Ref<StreamPeer>& p_connection); Ref<StreamPeer> get_connection() const; diff --git a/core/io/ip.cpp b/core/io/ip.cpp index a77aace07f..f0f273af1a 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -32,6 +32,7 @@ #include "hash_map.h" VARIANT_ENUM_CAST(IP::ResolverStatus); +VARIANT_ENUM_CAST(IP_Address::AddrType); /************* RESOLVER ******************/ @@ -43,10 +44,12 @@ struct _IP_ResolverPrivate { volatile IP::ResolverStatus status; IP_Address response; String hostname; + IP_Address::AddrType type; void clear() { status = IP::RESOLVER_STATUS_NONE; response = IP_Address(); + type = IP_Address::TYPE_NONE; hostname=""; }; @@ -78,9 +81,9 @@ struct _IP_ResolverPrivate { if (queue[i].status!=IP::RESOLVER_STATUS_WAITING) continue; - queue[i].response=IP::get_singleton()->resolve_hostname(queue[i].hostname); + queue[i].response=IP::get_singleton()->resolve_hostname(queue[i].hostname, queue[i].type); - if (queue[i].response.host==0) + if (queue[i].response.type==IP_Address::TYPE_NONE) queue[i].status=IP::RESOLVER_STATUS_ERROR; else queue[i].status=IP::RESOLVER_STATUS_DONE; @@ -109,21 +112,23 @@ struct _IP_ResolverPrivate { -IP_Address IP::resolve_hostname(const String& p_hostname) { +IP_Address IP::resolve_hostname(const String& p_hostname, IP_Address::AddrType p_type) { - GLOBAL_LOCK_FUNCTION + GLOBAL_LOCK_FUNCTION; if (resolver->cache.has(p_hostname)) - return resolver->cache[p_hostname]; + if (resolver->cache[p_hostname].type & p_type != 0) + return resolver->cache[p_hostname]; + // requested type is different from type in cache. continue resolution, if successful it'll overwrite cache - IP_Address res = _resolve_hostname(p_hostname); + IP_Address res = _resolve_hostname(p_hostname, p_type); resolver->cache[p_hostname]=res; return res; } -IP::ResolverID IP::resolve_hostname_queue_item(const String& p_hostname) { +IP::ResolverID IP::resolve_hostname_queue_item(const String& p_hostname, IP_Address::AddrType p_type) { - GLOBAL_LOCK_FUNCTION + GLOBAL_LOCK_FUNCTION; ResolverID id = resolver->find_empty_id(); @@ -133,7 +138,8 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String& p_hostname) { } resolver->queue[id].hostname=p_hostname; - if (resolver->cache.has(p_hostname)) { + resolver->queue[id].type = p_type; + if (resolver->cache.has(p_hostname) && (resolver->cache[p_hostname].type & p_type) != 0) { resolver->queue[id].response=resolver->cache[p_hostname]; resolver->queue[id].status=IP::RESOLVER_STATUS_DONE; } else { @@ -145,10 +151,6 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String& p_hostname) { resolver->resolve_queues(); } - - - - return id; } @@ -187,6 +189,14 @@ void IP::erase_resolve_item(ResolverID p_id) { } +void IP::clear_cache(const String &p_hostname) { + + if (p_hostname.empty()) { + resolver->cache.clear(); + } else { + resolver->cache.erase(p_hostname); + } +}; Array IP::_get_local_addresses() const { @@ -202,12 +212,13 @@ Array IP::_get_local_addresses() const { void IP::_bind_methods() { - ObjectTypeDB::bind_method(_MD("resolve_hostname","host"),&IP::resolve_hostname); - ObjectTypeDB::bind_method(_MD("resolve_hostname_queue_item","host"),&IP::resolve_hostname_queue_item); + ObjectTypeDB::bind_method(_MD("resolve_hostname","host","ip_type"),&IP::resolve_hostname,DEFVAL(IP_Address::TYPE_ANY)); + ObjectTypeDB::bind_method(_MD("resolve_hostname_queue_item","host","ip_type"),&IP::resolve_hostname_queue_item,DEFVAL(IP_Address::TYPE_ANY)); ObjectTypeDB::bind_method(_MD("get_resolve_item_status","id"),&IP::get_resolve_item_status); ObjectTypeDB::bind_method(_MD("get_resolve_item_address","id"),&IP::get_resolve_item_address); ObjectTypeDB::bind_method(_MD("erase_resolve_item","id"),&IP::erase_resolve_item); ObjectTypeDB::bind_method(_MD("get_local_addresses"),&IP::_get_local_addresses); + ObjectTypeDB::bind_method(_MD("clear_cache"),&IP::clear_cache, DEFVAL("")); BIND_CONSTANT( RESOLVER_STATUS_NONE ); BIND_CONSTANT( RESOLVER_STATUS_WAITING ); diff --git a/core/io/ip.h b/core/io/ip.h index 38c86e7ba3..742dd0e740 100644 --- a/core/io/ip.h +++ b/core/io/ip.h @@ -48,6 +48,14 @@ public: RESOLVER_STATUS_ERROR, }; + enum AddressType { + + ADDRESS_IPV4 = 1, + ADDRESS_IPV6 = 2, + + ADDRESS_ANY = 3, + }; + enum { RESOLVER_MAX_QUERIES = 32, RESOLVER_INVALID_ID=-1 @@ -65,7 +73,7 @@ protected: static IP*singleton; static void _bind_methods(); - virtual IP_Address _resolve_hostname(const String& p_hostname)=0; + virtual IP_Address _resolve_hostname(const String& p_hostname, IP_Address::AddrType p_type = IP_Address::TYPE_ANY)=0; Array _get_local_addresses() const; static IP* (*_create)(); @@ -73,14 +81,16 @@ public: - IP_Address resolve_hostname(const String& p_hostname); + IP_Address resolve_hostname(const String& p_hostname, IP_Address::AddrType p_type = IP_Address::TYPE_ANY); // async resolver hostname - ResolverID resolve_hostname_queue_item(const String& p_hostname); + ResolverID resolve_hostname_queue_item(const String& p_hostname, IP_Address::AddrType p_type = IP_Address::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=0; void erase_resolve_item(ResolverID p_id); + void clear_cache(const String& p_hostname = ""); + static IP* get_singleton(); static IP* create(); diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp index 7a51bce7c6..9887cd132b 100644 --- a/core/io/ip_address.cpp +++ b/core/io/ip_address.cpp @@ -32,29 +32,191 @@ IP_Address::operator Variant() const { return operator String(); }*/ + +#include <string.h> +#include <stdio.h> + IP_Address::operator String() const { - return itos(field[0])+"."+itos(field[1])+"."+itos(field[2])+"."+itos(field[3]); + if (type == TYPE_NONE) + return "0.0.0.0"; + if (type == TYPE_IPV4) + return itos(field8[0])+"."+itos(field8[1])+"."+itos(field8[2])+"."+itos(field8[3]); + else { + String ret; + for (int i=0; i<8; i++) { + if (i > 0) + ret = ret + ":"; + uint16_t num = (field8[i*2] << 8) + field8[i*2+1]; + ret = ret + String::num_int64(num, 16); + }; + + return ret; + }; } -IP_Address::IP_Address(const String& p_string) { +static void _parse_hex(const String& p_string, int p_start, uint8_t* p_dst) { + + uint16_t ret = 0; + for (int i=p_start; i<p_start + 4; i++) { + + if (i >= p_string.length()) { + break; + }; + + int n = 0; + CharType c = p_string[i]; + if (c >= '0' && c <= '9') { + + n = c - '0'; + } else if (c >= 'a' && c <= 'f') { + n = 10 + (c - 'a'); + } else if (c >= 'A' && c <= 'F') { + n = 10 + (c - 'A'); + } else if (c == ':') { + break; + } else { + ERR_EXPLAIN("Invalid character in ipv6 address: " + p_string); + ERR_FAIL(); + }; + ret = ret << 4; + ret += n; + }; + + p_dst[0] = ret >> 8; + p_dst[1] = ret & 0xff; +}; + +void IP_Address::_parse_ipv6(const String& p_string) { + + static const int parts_total = 8; + int parts[parts_total] = {0}; + int parts_count = 0; + bool part_found = false; + bool part_skip = false; + bool part_ipv4 = false; + int parts_idx = 0; + + for (int i=0; i<p_string.length(); i++) { + + CharType c = p_string[i]; + if (c == ':') { + + if (i == 0) { + continue; // next must be a ":" + }; + if (!part_found) { + part_skip = true; + parts[parts_idx++] = -1; + }; + part_found = false; + } else if (c == '.') { + + part_ipv4 = true; + + } else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { + if (!part_found) { + parts[parts_idx++] = i; + part_found = true; + ++parts_count; + }; + } else { + + ERR_EXPLAIN("Invalid character in IPv6 address: " + p_string); + ERR_FAIL(); + }; + }; + + int parts_extra = 0; + if (part_skip) { + parts_extra = parts_total - parts_count; + }; + + int idx = 0; + for (int i=0; i<parts_idx; i++) { - host=0; - int slices = p_string.get_slice_count("."); + if (parts[i] == -1) { + + for (int j=0; j<parts_extra; j++) { + field16[idx++] = 0; + }; + continue; + }; + + if (part_ipv4 && i == parts_idx - 1) { + _parse_ipv4(p_string, parts[i], (uint8_t*)&field16[idx]); // should be the last one + } else { + _parse_hex(p_string, parts[i], (uint8_t*)&(field16[idx++])); + }; + }; + +}; + +void IP_Address::_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); + } else { + ip = p_string; + }; + + int slices = ip.get_slice_count("."); if (slices!=4) { - ERR_EXPLAIN("Invalid IP Address String: "+p_string); + ERR_EXPLAIN("Invalid IP Address String: "+ip); ERR_FAIL(); } for(int i=0;i<4;i++) { - - field[i]=p_string.get_slicec('.',i).to_int(); + p_ret[i]=ip.get_slicec('.',i).to_int(); } +}; + +void IP_Address::clear() { + + memset(&field8[0], 0, sizeof(field8)); +}; + +IP_Address::IP_Address(const String& p_string) { + + clear(); + if (p_string.find(":") >= 0) { + + _parse_ipv6(p_string); + type = TYPE_IPV6; + } else { + + _parse_ipv4(p_string, 0, &field8[0]); + type = TYPE_IPV4; + }; } -IP_Address::IP_Address(uint8_t p_a,uint8_t p_b,uint8_t p_c,uint8_t p_d) { +_FORCE_INLINE_ static void _32_to_buf(uint8_t* p_dst, uint32_t p_n) { + + p_dst[0] = (p_n >> 24) & 0xff; + p_dst[1] = (p_n >> 16) & 0xff; + p_dst[2] = (p_n >> 8) & 0xff; + 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, IP_Address::AddrType p_type) { + + type = p_type; + memset(&field8[0], 0, sizeof(field8)); + if (p_type == TYPE_IPV4) { + field8[0]=p_a; + field8[1]=p_b; + field8[2]=p_c; + field8[3]=p_d; + } else if (type == TYPE_IPV6) { + + _32_to_buf(&field8[0], p_a); + _32_to_buf(&field8[4], p_b); + _32_to_buf(&field8[8], p_c); + _32_to_buf(&field8[12], p_d); + } else { + type = TYPE_NONE; + ERR_EXPLAIN("Invalid type specified for IP_Address (use TYPE_IPV4 or TYPE_IPV6"); + ERR_FAIL(); + }; - field[0]=p_a; - field[1]=p_b; - field[2]=p_c; - field[3]=p_d; } diff --git a/core/io/ip_address.h b/core/io/ip_address.h index 1292311729..fe13d70611 100644 --- a/core/io/ip_address.h +++ b/core/io/ip_address.h @@ -33,22 +33,48 @@ struct IP_Address { +public: + enum AddrType { + TYPE_NONE = 0, + TYPE_IPV4 = 1, + TYPE_IPV6 = 2, + + TYPE_ANY = 3, + }; + + AddrType type; + union { - uint8_t field[4]; - uint32_t host; + uint8_t field8[16]; + uint16_t field16[8]; + uint32_t field32[4]; }; +protected: + void _parse_ipv6(const String& p_string); + void _parse_ipv4(const String& p_string, int p_start, uint8_t* p_ret); + +public: //operator Variant() const; bool operator==(const IP_Address& p_ip) const { - return host==p_ip.host; + for (int i=0; i<4; i++) + if (field32[i] != p_ip.field32[i]) + return false; + return true; } bool operator!=(const IP_Address& p_ip) const { - return host!=p_ip.host; + for (int i=0; i<4; i++) + if (field32[i] != p_ip.field32[i]) + return true; + return false; } + + void clear(); + operator String() const; IP_Address(const String& p_string); - IP_Address(uint8_t p_a,uint8_t p_b,uint8_t p_c,uint8_t p_d); - IP_Address() { host=0; } + IP_Address(uint32_t p_a,uint32_t p_b,uint32_t p_c,uint32_t p_d, AddrType p_type=TYPE_IPV4); + IP_Address() { clear(); type=TYPE_NONE; } }; diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp index efc619e414..925d00a84a 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -29,27 +29,22 @@ #include "packet_peer_udp.h" #include "io/ip.h" - PacketPeerUDP* (*PacketPeerUDP::_create)()=NULL; -int PacketPeerUDP::_get_packet_address() const { - - IP_Address ip = get_packet_address(); - return ip.host; -} +VARIANT_ENUM_CAST(IP_Address::AddrType); String PacketPeerUDP::_get_packet_ip() const { return get_packet_address(); } -Error PacketPeerUDP::_set_send_address(const String& p_address,int p_port) { +Error PacketPeerUDP::_set_send_address(const String& p_address,int p_port,IP_Address::AddrType p_type) { IP_Address ip; if (p_address.is_valid_ip_address()) { ip=p_address; } else { - ip=IP::get_singleton()->resolve_hostname(p_address); + ip=IP::get_singleton()->resolve_hostname(p_address, p_type); if (ip==IP_Address()) return ERR_CANT_RESOLVE; } @@ -60,14 +55,14 @@ Error PacketPeerUDP::_set_send_address(const String& p_address,int p_port) { void PacketPeerUDP::_bind_methods() { - ObjectTypeDB::bind_method(_MD("listen:Error","port","recv_buf_size"),&PacketPeerUDP::listen,DEFVAL(65536)); + ObjectTypeDB::bind_method(_MD("listen:Error","port","ip_type", "recv_buf_size"),&PacketPeerUDP::listen,DEFVAL(IP_Address::TYPE_ANY),DEFVAL(65536)); ObjectTypeDB::bind_method(_MD("close"),&PacketPeerUDP::close); ObjectTypeDB::bind_method(_MD("wait:Error"),&PacketPeerUDP::wait); ObjectTypeDB::bind_method(_MD("is_listening"),&PacketPeerUDP::is_listening); ObjectTypeDB::bind_method(_MD("get_packet_ip"),&PacketPeerUDP::_get_packet_ip); - ObjectTypeDB::bind_method(_MD("get_packet_address"),&PacketPeerUDP::_get_packet_address); + //ObjectTypeDB::bind_method(_MD("get_packet_address"),&PacketPeerUDP::_get_packet_address); ObjectTypeDB::bind_method(_MD("get_packet_port"),&PacketPeerUDP::get_packet_port); - ObjectTypeDB::bind_method(_MD("set_send_address","host","port"),&PacketPeerUDP::_set_send_address); + ObjectTypeDB::bind_method(_MD("set_send_address","host","port","ip_type"),&PacketPeerUDP::_set_send_address,DEFVAL(IP_Address::TYPE_ANY)); } diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h index 70d92834fc..37e700cebd 100644 --- a/core/io/packet_peer_udp.h +++ b/core/io/packet_peer_udp.h @@ -40,14 +40,13 @@ protected: static PacketPeerUDP* (*_create)(); static void _bind_methods(); - int _get_packet_address() const; String _get_packet_ip() const; - virtual Error _set_send_address(const String& p_address,int p_port); + virtual Error _set_send_address(const String& p_address,int p_port, IP_Address::AddrType p_address_type = IP_Address::TYPE_ANY); public: - virtual Error listen(int p_port,int p_recv_buffer_size=65536)=0; + virtual Error listen(int p_port, IP_Address::AddrType p_address_type = IP_Address::TYPE_ANY, int p_recv_buffer_size=65536)=0; virtual void close()=0; virtual Error wait()=0; virtual bool is_listening() const=0; diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index fbb0c69cb7..528f2e8cab 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -30,9 +30,26 @@ StreamPeerTCP* (*StreamPeerTCP::_create)()=NULL; +VARIANT_ENUM_CAST(IP_Address::AddrType); + +Error StreamPeerTCP::_connect(const String& p_address,int p_port,IP_Address::AddrType p_type) { + + IP_Address ip; + if (p_address.is_valid_ip_address()) { + ip=p_address; + } else { + ip=IP::get_singleton()->resolve_hostname(p_address, p_type); + if (ip==IP_Address()) + return ERR_CANT_RESOLVE; + } + + connect(ip,p_port); + return OK; +} + void StreamPeerTCP::_bind_methods() { - ObjectTypeDB::bind_method(_MD("connect","host","port"),&StreamPeerTCP::connect); + ObjectTypeDB::bind_method(_MD("connect","host","port","ip_type"),&StreamPeerTCP::_connect,DEFVAL(IP_Address::TYPE_ANY)); ObjectTypeDB::bind_method(_MD("is_connected"),&StreamPeerTCP::is_connected); ObjectTypeDB::bind_method(_MD("get_status"),&StreamPeerTCP::get_status); ObjectTypeDB::bind_method(_MD("get_connected_host"),&StreamPeerTCP::get_connected_host); diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h index 4c58e7e149..a151fffad8 100644 --- a/core/io/stream_peer_tcp.h +++ b/core/io/stream_peer_tcp.h @@ -32,6 +32,7 @@ #include "stream_peer.h" #include "ip_address.h" +#include "io/ip.h" class StreamPeerTCP : public StreamPeer { @@ -50,6 +51,7 @@ public: protected: + virtual Error _connect(const String& p_address, int p_port, IP_Address::AddrType p_type = IP_Address::TYPE_ANY); static StreamPeerTCP* (*_create)(); static void _bind_methods(); diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp index 274d20a48a..894cccf691 100644 --- a/core/io/tcp_server.cpp +++ b/core/io/tcp_server.cpp @@ -30,6 +30,8 @@ TCP_Server* (*TCP_Server::_create)()=NULL; +VARIANT_ENUM_CAST(IP_Address::AddrType); + Ref<TCP_Server> TCP_Server::create_ref() { if (!_create) @@ -44,19 +46,19 @@ TCP_Server* TCP_Server::create() { return _create(); } -Error TCP_Server::_listen(uint16_t p_port,DVector<String> p_accepted_hosts) { +Error TCP_Server::_listen(uint16_t p_port, IP_Address::AddrType p_type, DVector<String> p_accepted_hosts) { List<String> hosts; for(int i=0;i<p_accepted_hosts.size();i++) hosts.push_back(p_accepted_hosts.get(i)); - return listen(p_port,hosts.size()?&hosts:NULL); + return listen(p_port,p_type, hosts.size()?&hosts:NULL); } void TCP_Server::_bind_methods() { - ObjectTypeDB::bind_method(_MD("listen","port","accepted_hosts"),&TCP_Server::_listen,DEFVAL(DVector<String>())); + ObjectTypeDB::bind_method(_MD("listen","port","ip_type", "accepted_hosts"),&TCP_Server::_listen,DEFVAL(IP_Address::TYPE_ANY),DEFVAL(DVector<String>())); ObjectTypeDB::bind_method(_MD("is_connection_available"),&TCP_Server::is_connection_available); ObjectTypeDB::bind_method(_MD("take_connection"),&TCP_Server::take_connection); ObjectTypeDB::bind_method(_MD("stop"),&TCP_Server::stop); diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h index 512a7e640a..0267895008 100644 --- a/core/io/tcp_server.h +++ b/core/io/tcp_server.h @@ -41,11 +41,11 @@ protected: static TCP_Server* (*_create)(); //bind helper - Error _listen(uint16_t p_port,DVector<String> p_accepted_hosts=DVector<String>()); + Error _listen(uint16_t p_port, IP_Address::AddrType p_type = IP_Address::TYPE_ANY ,DVector<String> p_accepted_hosts=DVector<String>()); static void _bind_methods(); public: - virtual Error listen(uint16_t p_port,const List<String> *p_accepted_hosts=NULL)=0; + virtual Error listen(uint16_t p_port, IP_Address::AddrType p_type = IP_Address::TYPE_ANY, const List<String> *p_accepted_hosts=NULL)=0; virtual bool is_connection_available() const=0; virtual Ref<StreamPeerTCP> take_connection()=0; diff --git a/core/make_binders.py b/core/make_binders.py index 7584722965..ef71c4264b 100644 --- a/core/make_binders.py +++ b/core/make_binders.py @@ -1,7 +1,7 @@ # -*- coding: ibm850 -*- -template_typed=""" +template_typed = """ #ifdef TYPED_METHOD_BIND template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$> class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind { @@ -77,7 +77,7 @@ MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$ #endif """ -template=""" +template = """ #ifndef TYPED_METHOD_BIND $iftempl template<$ $ifret class R$ $ifretargs ,$ $arg, class P@$ $iftempl >$ class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind { @@ -166,96 +166,95 @@ MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$ """ -def make_version(template,nargs,argmax,const,ret): - - intext=template - from_pos=0 - outtext="" - - while(True): - to_pos=intext.find("$",from_pos) - if (to_pos==-1): - outtext+=intext[from_pos:] - break - else: - outtext+=intext[from_pos:to_pos] - end=intext.find("$",to_pos+1) - if (end==-1): - break # ignore - macro=intext[to_pos+1:end] - cmd="" - data="" - - if (macro.find(" ")!=-1): - cmd=macro[0:macro.find(" ")] - data=macro[macro.find(" ")+1:] - else: - cmd=macro - - if (cmd=="argc"): - outtext+=str(nargs) - if (cmd=="ifret" and ret): - outtext+=data - if (cmd=="ifargs" and nargs): - outtext+=data - if (cmd=="ifretargs" and nargs and ret): - outtext+=data - if (cmd=="ifconst" and const): - outtext+=data - elif (cmd=="ifnoconst" and not const): - outtext+=data - elif (cmd=="ifnoret" and not ret): - outtext+=data - elif (cmd=="iftempl" and (nargs>0 or ret)): - outtext+=data - elif (cmd=="arg,"): - for i in range(1,nargs+1): - if (i>1): - outtext+=", " - outtext+=data.replace("@",str(i)) - elif (cmd=="arg"): - for i in range(1,nargs+1): - outtext+=data.replace("@",str(i)) - elif (cmd=="noarg"): - for i in range(nargs+1,argmax+1): - outtext+=data.replace("@",str(i)) - elif (cmd=="noarg"): - for i in range(nargs+1,argmax+1): - outtext+=data.replace("@",str(i)) - - from_pos=end+1 - - return outtext +def make_version(template, nargs, argmax, const, ret): + + intext = template + from_pos = 0 + outtext = "" + + while(True): + to_pos = intext.find("$", from_pos) + if (to_pos == -1): + outtext += intext[from_pos:] + break + else: + outtext += intext[from_pos:to_pos] + end = intext.find("$", to_pos + 1) + if (end == -1): + break # ignore + macro = intext[to_pos + 1:end] + cmd = "" + data = "" + + if (macro.find(" ") != -1): + cmd = macro[0:macro.find(" ")] + data = macro[macro.find(" ") + 1:] + else: + cmd = macro + + if (cmd == "argc"): + outtext += str(nargs) + if (cmd == "ifret" and ret): + outtext += data + if (cmd == "ifargs" and nargs): + outtext += data + if (cmd == "ifretargs" and nargs and ret): + outtext += data + if (cmd == "ifconst" and const): + outtext += data + elif (cmd == "ifnoconst" and not const): + outtext += data + elif (cmd == "ifnoret" and not ret): + outtext += data + elif (cmd == "iftempl" and (nargs > 0 or ret)): + outtext += data + elif (cmd == "arg,"): + for i in range(1, nargs + 1): + if (i > 1): + outtext += ", " + outtext += data.replace("@", str(i)) + elif (cmd == "arg"): + for i in range(1, nargs + 1): + outtext += data.replace("@", str(i)) + elif (cmd == "noarg"): + for i in range(nargs + 1, argmax + 1): + outtext += data.replace("@", str(i)) + elif (cmd == "noarg"): + for i in range(nargs + 1, argmax + 1): + outtext += data.replace("@", str(i)) + + from_pos = end + 1 + + return outtext def run(target, source, env): - versions=10 - versions_ext=6 - text="" - text_ext="" - - for i in range(0,versions+1): - - t="" - t+=make_version(template,i,versions,False,False) - t+=make_version(template_typed,i,versions,False,False) - t+=make_version(template,i,versions,False,True) - t+=make_version(template_typed,i,versions,False,True) - t+=make_version(template,i,versions,True,False) - t+=make_version(template_typed,i,versions,True,False) - t+=make_version(template,i,versions,True,True) - t+=make_version(template_typed,i,versions,True,True) - if (i>=versions_ext): - text_ext+=t - else: - text+=t - - - f=open(target[0].path,"w") - f.write(text) - f.close() - - f=open(target[1].path,"w") - f.write(text_ext) - f.close() + versions = 10 + versions_ext = 6 + text = "" + text_ext = "" + + for i in range(0, versions + 1): + + t = "" + t += make_version(template, i, versions, False, False) + t += make_version(template_typed, i, versions, False, False) + t += make_version(template, i, versions, False, True) + t += make_version(template_typed, i, versions, False, True) + t += make_version(template, i, versions, True, False) + t += make_version(template_typed, i, versions, True, False) + t += make_version(template, i, versions, True, True) + t += make_version(template_typed, i, versions, True, True) + if (i >= versions_ext): + text_ext += t + else: + text += t + + f = open(target[0].path, "w") + f.write(text) + f.close() + + f = open(target[1].path, "w") + f.write(text_ext) + f.close() diff --git a/core/math/SCsub b/core/math/SCsub index c2731d60e6..4efc902717 100644 --- a/core/math/SCsub +++ b/core/math/SCsub @@ -2,6 +2,6 @@ Import('env') -env.add_source_files(env.core_sources,"*.cpp") +env.add_source_files(env.core_sources, "*.cpp") Export('env') diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 5bbbbdaa5a..198d9f6076 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -1,3 +1,31 @@ +/*************************************************************************/ +/* a_star.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ #include "a_star.h" #include "geometry.h" diff --git a/core/math/a_star.h b/core/math/a_star.h index a0517b5941..26f3a85046 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -1,8 +1,39 @@ +/*************************************************************************/ +/* a_star.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ #ifndef ASTAR_H #define ASTAR_H #include "reference.h" #include "self_list.h" +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ class AStar: public Reference { diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index 64615fe6b4..46c0218707 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -41,37 +41,16 @@ static uint32_t Q[4096]; #endif uint32_t Math::rand_from_seed(uint32_t *seed) { - -#if 1 - uint32_t k; - uint32_t s = (*seed); - if (s == 0) - s = 0x12345987; - k = s / 127773; - s = 16807 * (s - k * 127773) - 2836 * k; -// if (s < 0) -// s += 2147483647; - (*seed) = s; - return (s & Math::RANDOM_MAX); -#else - *seed = *seed * 1103515245 + 12345; - return (*seed % ((unsigned int)RANDOM_MAX + 1)); -#endif + // Xorshift31 PRNG + if ( *seed == 0 ) *seed = Math::RANDOM_MAX; + (*seed) ^= (*seed) << 13; + (*seed) ^= (*seed) >> 17; + (*seed) ^= (*seed) << 5; + return (*seed) & Math::RANDOM_MAX; } void Math::seed(uint32_t x) { -#if 0 - int i; - - Q[0] = x; - Q[1] = x + PHI; - Q[2] = x + PHI + PHI; - - for (i = 3; i < 4096; i++) - Q[i] = Q[i - 3] ^ Q[i - 2] ^ PHI ^ i; -#else default_seed=x; -#endif } void Math::randomize() { @@ -82,12 +61,12 @@ void Math::randomize() { uint32_t Math::rand() { - return rand_from_seed(&default_seed)&0x7FFFFFFF; + return rand_from_seed(&default_seed); } double Math::randf() { - return (double)rand() / (double)RANDOM_MAX; + return (double)rand() / (double)Math::RANDOM_MAX; } double Math::sin(double p_x) { diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp index 1f5d5ed6b3..eaf019f200 100644 --- a/core/math/triangulate.cpp +++ b/core/math/triangulate.cpp @@ -71,7 +71,7 @@ bool Triangulate::is_inside_triangle(float Ax, float Ay, return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); }; -bool Triangulate::snip(const Vector<Vector2> &p_contour,int u,int v,int w,int n,int *V) +bool Triangulate::snip(const Vector<Vector2> &p_contour,int u,int v,int w,int n,const Vector<int>& V) { int p; float Ax, Ay, Bx, By, Cx, Cy, Px, Py; @@ -107,8 +107,8 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour,Vector<int> &result if ( n < 3 ) return false; - - int *V = (int*)alloca(sizeof(int)*n); + Vector<int> V; + V.resize(n); /* we want a counter-clockwise polygon in V */ @@ -122,7 +122,7 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour,Vector<int> &result /* remove nv-2 Vertices, creating 1 triangle every time */ int count = 2*nv; /* error detection */ - for(int m=0, v=nv-1; nv>2; ) + for(int v=nv-1; nv>2; ) { /* if we loop, it is probably a non-simple polygon */ if (0 >= (count--)) @@ -144,18 +144,10 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour,Vector<int> &result a = V[u]; b = V[v]; c = V[w]; /* output Triangle */ - /* - result.push_back( contour[a] ); - result.push_back( contour[b] ); - result.push_back( contour[c] ); -*/ - result.push_back( a ); result.push_back( b ); result.push_back( c ); - m++; - /* remove v from remaining polygon */ for(s=v,t=v+1;t<nv;s++,t++) V[s] = V[t]; diff --git a/core/math/triangulate.h b/core/math/triangulate.h index 7dcc91b2fd..ef622b5005 100644 --- a/core/math/triangulate.h +++ b/core/math/triangulate.h @@ -56,7 +56,7 @@ public: private: - static bool snip(const Vector<Vector2> &p_contour,int u,int v,int w,int n,int *V); + static bool snip(const Vector<Vector2> &p_contour,int u,int v,int w,int n,const Vector<int>& V); }; diff --git a/core/os/SCsub b/core/os/SCsub index c2731d60e6..4efc902717 100644 --- a/core/os/SCsub +++ b/core/os/SCsub @@ -2,6 +2,6 @@ Import('env') -env.add_source_files(env.core_sources,"*.cpp") +env.add_source_files(env.core_sources, "*.cpp") Export('env') diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp index 9982767be1..7350be824a 100644 --- a/core/os/input_event.cpp +++ b/core/os/input_event.cpp @@ -50,7 +50,8 @@ bool InputEvent::operator==(const InputEvent &p_event) const { case MOUSE_MOTION: return mouse_motion.x == p_event.mouse_motion.x && mouse_motion.y == p_event.mouse_motion.y - && mouse_motion.relative_x == p_event.mouse_motion.relative_y + && mouse_motion.relative_x == p_event.mouse_motion.relative_x + && mouse_motion.relative_y == p_event.mouse_motion.relative_y && mouse_motion.button_mask == p_event.mouse_motion.button_mask && key.mod == p_event.key.mod; case MOUSE_BUTTON: diff --git a/core/os/os.cpp b/core/os/os.cpp index ee32476234..11a315a01b 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -542,7 +542,7 @@ void OS::set_use_vsync(bool p_enable) { } -bool OS::is_vsnc_enabled() const{ +bool OS::is_vsync_enabled() const{ return true; } diff --git a/core/os/os.h b/core/os/os.h index c2b46a5420..037fcac039 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -431,7 +431,7 @@ public: virtual void set_context(int p_context); virtual void set_use_vsync(bool p_enable); - virtual bool is_vsnc_enabled() const; + virtual bool is_vsync_enabled() const; Dictionary get_engine_version() const; diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index c3a127afb9..4c9d121781 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -177,7 +177,7 @@ void register_core_singletons() { Globals::get_singleton()->add_singleton( Globals::Singleton("ResourceSaver",_ResourceSaver::get_singleton()) ); Globals::get_singleton()->add_singleton( Globals::Singleton("PathRemap",PathRemap::get_singleton() ) ); Globals::get_singleton()->add_singleton( Globals::Singleton("OS",_OS::get_singleton() ) ); - Globals::get_singleton()->add_singleton( Globals::Singleton("Marshalls",_marshalls ) ); + Globals::get_singleton()->add_singleton( Globals::Singleton("Marshalls",_Marshalls::get_singleton() ) ); Globals::get_singleton()->add_singleton( Globals::Singleton("TranslationServer",TranslationServer::get_singleton() ) ); Globals::get_singleton()->add_singleton( Globals::Singleton("TS",TranslationServer::get_singleton() ) ); Globals::get_singleton()->add_singleton( Globals::Singleton("Input",Input::get_singleton() ) ); diff --git a/core/translation.cpp b/core/translation.cpp index 4592d00598..4d81073fe6 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -779,6 +779,11 @@ Vector<String> TranslationServer::get_all_locale_names(){ } +static String get_trimmed_locale(const String& p_locale) { + + return p_locale.substr(0,2); +} + static bool is_valid_locale(const String& p_locale) { const char **ptr=locale_list; @@ -839,9 +844,20 @@ void Translation::_set_messages(const DVector<String>& p_messages){ void Translation::set_locale(const String& p_locale) { - ERR_EXPLAIN("Invalid Locale: "+p_locale); - ERR_FAIL_COND(!is_valid_locale(p_locale)); - locale=p_locale; + // replaces '-' with '_' for macOS Sierra-style locales + String univ_locale = p_locale.replace("-", "_"); + + if(!is_valid_locale(univ_locale)) { + String trimmed_locale = get_trimmed_locale(univ_locale); + + ERR_EXPLAIN("Invalid Locale: "+trimmed_locale); + ERR_FAIL_COND(!is_valid_locale(trimmed_locale)); + + locale=trimmed_locale; + } + else { + locale=univ_locale; + } } void Translation::add_message( const StringName& p_src_text, const StringName& p_xlated_text ) { @@ -906,9 +922,20 @@ Translation::Translation() { void TranslationServer::set_locale(const String& p_locale) { - ERR_EXPLAIN("Invalid Locale: "+p_locale); - ERR_FAIL_COND(!is_valid_locale(p_locale)); - locale=p_locale; + // replaces '-' with '_' for macOS Sierra-style locales + String univ_locale = p_locale.replace("-", "_"); + + if(!is_valid_locale(univ_locale)) { + String trimmed_locale = get_trimmed_locale(univ_locale); + + ERR_EXPLAIN("Invalid Locale: "+trimmed_locale); + ERR_FAIL_COND(!is_valid_locale(trimmed_locale)); + + locale=trimmed_locale; + } + else { + locale=univ_locale; + } } String TranslationServer::get_locale() const { diff --git a/core/ustring.cpp b/core/ustring.cpp index 2e907381f7..f9c10615b3 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -1543,11 +1543,11 @@ String::String(const StrRange& p_range) { copy_from(p_range.c_str,p_range.len); } -int String::hex_to_int() const { +int String::hex_to_int(bool p_with_prefix) const { int l = length(); - if (l<3) - return 0; + if (p_with_prefix && l<3) + return 0; const CharType *s=ptr(); @@ -1556,15 +1556,16 @@ int String::hex_to_int() const { if (sign<0) { s++; l--; - if (l<2) + if (p_with_prefix && l<2) return 0; } - if (s[0]!='0' || s[1]!='x') - return 0; - - s+=2; - l-=2; + if (p_with_prefix) { + if (s[0]!='0' || s[1]!='x') + return 0; + s+=2; + l-=2; + }; int hex=0; @@ -3510,6 +3511,36 @@ bool String::is_valid_integer() const { } +bool String::is_valid_hex_number(bool p_with_prefix) const { + + int from = 0; + int len = length(); + + if (len!=1 && (operator[](0)=='+' || operator[](0)=='-')) + from++; + + if (p_with_prefix) { + + if (len < 2) + return false; + if (operator[](from) != '0' || operator[](from+1) != 'x') { + return false; + }; + from += 2; + }; + + for (int i=from; i<len; i++) { + + CharType c = operator[](i); + if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) + continue; + return false; + }; + + return true; +}; + + bool String::is_valid_float() const { int len = length(); @@ -3646,20 +3677,41 @@ bool String::is_valid_html_color() const { } + bool String::is_valid_ip_address() const { - Vector<String> ip = split("."); - if (ip.size()!=4) - return false; - for(int i=0;i<ip.size();i++) { + if (find(":") >= 0) { - String n = ip[i]; - if (!n.is_valid_integer()) - return false; - int val = n.to_int(); - if (val<0 || val>255) + Vector<String> ip = split(":"); + for (int i=0; i<ip.size(); i++) { + + String n = ip[i]; + if (n.empty()) + continue; + if (n.is_valid_hex_number(false)) { + int nint = n.hex_to_int(false); + if (nint < 0 || nint > 0xffff) + return false; + continue; + }; + if (!n.is_valid_ip_address()) + return false; + }; + + } else { + Vector<String> ip = split("."); + if (ip.size()!=4) return false; - } + for(int i=0;i<ip.size();i++) { + + String n = ip[i]; + if (!n.is_valid_integer()) + return false; + int val = n.to_int(); + if (val<0 || val>255) + return false; + } + }; return true; } diff --git a/core/ustring.h b/core/ustring.h index 09d13a9e64..452f252857 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -144,7 +144,7 @@ public: bool is_numeric() const; double to_double() const; float to_float() const; - int hex_to_int() const; + int hex_to_int(bool p_with_prefix = true) const; int to_int() const; int64_t to_int64() const; @@ -226,6 +226,7 @@ public: bool is_valid_identifier() const; bool is_valid_integer() const; bool is_valid_float() const; + bool is_valid_hex_number(bool p_with_prefix) const; bool is_valid_html_color() const; bool is_valid_ip_address() const; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 51cd4c2399..9b6fa27cf4 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -1820,6 +1820,11 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl _VariantCall::add_constant(Variant::IMAGE,"INTERPOLATE_NEAREST",Image::INTERPOLATE_NEAREST); _VariantCall::add_constant(Variant::IMAGE,"INTERPOLATE_BILINEAR",Image::INTERPOLATE_BILINEAR); _VariantCall::add_constant(Variant::IMAGE,"INTERPOLATE_CUBIC",Image::INTERPOLATE_CUBIC); + + _VariantCall::add_constant(Variant::INT, "IP_TYPE_NONE", IP_Address::TYPE_NONE); + _VariantCall::add_constant(Variant::INT, "IP_TYPE_IPV4", IP_Address::TYPE_IPV4); + _VariantCall::add_constant(Variant::INT, "IP_TYPE_IPV6", IP_Address::TYPE_IPV6); + _VariantCall::add_constant(Variant::INT, "IP_TYPE_ANY", IP_Address::TYPE_ANY); } void unregister_variant_methods() { |