summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/bullet/godot_result_callbacks.cpp22
-rw-r--r--modules/bullet/godot_result_callbacks.h5
-rw-r--r--modules/bullet/shape_bullet.cpp4
-rw-r--r--modules/bullet/space_bullet.cpp7
-rw-r--r--modules/gdnative/gdnative.cpp231
-rw-r--r--modules/gdnative/gdnative.h6
-rw-r--r--modules/gdnative/include/nativescript/godot_nativescript.h6
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp38
-rw-r--r--modules/gdscript/gdscript_editor.cpp27
-rw-r--r--modules/gdscript/gdscript_highlighter.cpp278
-rw-r--r--modules/gdscript/gdscript_highlighter.h56
-rw-r--r--modules/gdscript/register_types.cpp2
-rwxr-xr-xmodules/mbedtls/stream_peer_mbed_tls.cpp26
-rwxr-xr-xmodules/mbedtls/stream_peer_mbed_tls.h2
-rw-r--r--modules/mono/editor/godotsharp_builds.cpp13
-rw-r--r--modules/mono/editor/mono_bottom_panel.cpp23
-rw-r--r--modules/mono/glue/cs_files/Basis.cs12
-rw-r--r--modules/mono/glue/cs_files/Mathf.cs12
-rw-r--r--modules/theora/video_stream_theora.cpp20
-rw-r--r--modules/visual_script/visual_script_editor.cpp6
-rw-r--r--modules/visual_script/visual_script_editor.h3
-rw-r--r--modules/webm/libvpx/SCsub2
-rw-r--r--modules/websocket/lws_client.cpp20
-rw-r--r--modules/websocket/websocket_client.cpp16
-rw-r--r--modules/websocket/websocket_client.h4
25 files changed, 679 insertions, 162 deletions
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp
index 72c982bb0b..caa3d677dd 100644
--- a/modules/bullet/godot_result_callbacks.cpp
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -63,6 +63,9 @@ bool GodotClosestRayResultCallback::needsCollision(btBroadphaseProxy *proxy0) co
}
bool GodotAllConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
+ if (count >= m_resultMax)
+ return false;
+
const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
if (needs) {
btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
@@ -70,6 +73,7 @@ bool GodotAllConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) con
if (m_exclude->has(gObj->get_self())) {
return false;
}
+
return true;
} else {
return false;
@@ -87,7 +91,7 @@ btScalar GodotAllConvexResultCallback::addSingleResult(btCollisionWorld::LocalCo
result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id);
++count;
- return count < m_resultMax;
+ return 1; // not used by bullet
}
bool GodotKinClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
@@ -181,6 +185,9 @@ btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, con
}
bool GodotContactPairContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
+ if (m_count >= m_resultMax)
+ return false;
+
const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
if (needs) {
btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
@@ -206,7 +213,7 @@ btScalar GodotContactPairContactResultCallback::addSingleResult(btManifoldPoint
++m_count;
- return m_count < m_resultMax;
+ return 1; // Not used by bullet
}
bool GodotRestInfoContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
@@ -252,20 +259,17 @@ btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp
m_collided = true;
}
- return cp.getDistance();
+ return 1; // Not used by bullet
}
void GodotDeepPenetrationContactResultCallback::addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorldOnB, btScalar depth) {
- // Has penetration
- if (m_penetration_distance < ABS(depth)) {
+ if (m_penetration_distance > depth) { // Has penetration?
bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
-
m_penetration_distance = depth;
- m_pointCollisionObject = (isSwapped ? m_body0Wrap : m_body1Wrap)->getCollisionObject();
- m_other_compound_shape_index = isSwapped ? m_index1 : m_index0;
+ m_other_compound_shape_index = isSwapped ? m_index0 : m_index1;
m_pointNormalWorld = isSwapped ? normalOnBInWorld * -1 : normalOnBInWorld;
- m_pointWorld = isSwapped ? (pointInWorldOnB + normalOnBInWorld * depth) : pointInWorldOnB;
+ m_pointWorld = isSwapped ? (pointInWorldOnB + (normalOnBInWorld * depth)) : pointInWorldOnB;
}
}
diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h
index 60493d4788..363051f24c 100644
--- a/modules/bullet/godot_result_callbacks.h
+++ b/modules/bullet/godot_result_callbacks.h
@@ -185,21 +185,18 @@ struct GodotDeepPenetrationContactResultCallback : public btManifoldResult {
btVector3 m_pointWorld;
btScalar m_penetration_distance;
int m_other_compound_shape_index;
- const btCollisionObject *m_pointCollisionObject;
GodotDeepPenetrationContactResultCallback(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap) :
btManifoldResult(body0Wrap, body1Wrap),
- m_pointCollisionObject(NULL),
m_penetration_distance(0),
m_other_compound_shape_index(0) {}
void reset() {
- m_pointCollisionObject = NULL;
m_penetration_distance = 0;
}
bool hasHit() {
- return m_pointCollisionObject;
+ return m_penetration_distance < 0;
}
virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorldOnB, btScalar depth);
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index 5d8d391bd9..9cbf83689b 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -337,10 +337,10 @@ void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) {
int src_face_count = faces.size();
if (0 < src_face_count) {
- btTriangleMesh *shapeInterface = bulletnew(btTriangleMesh);
-
// It counts the faces and assert the array contains the correct number of vertices.
ERR_FAIL_COND(src_face_count % 3);
+
+ btTriangleMesh *shapeInterface = bulletnew(btTriangleMesh);
src_face_count /= 3;
PoolVector<Vector3>::Read r = p_faces.read();
const Vector3 *facesr = r.ptr();
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index 8c15758e0f..51a76ff8c5 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -660,7 +660,10 @@ void SpaceBullet::check_ghost_overlaps() {
// For each overlapping
for (i = ghostOverlaps.size() - 1; 0 <= i; --i) {
- if (!(ghostOverlaps[i]->getUserIndex() == CollisionObjectBullet::TYPE_RIGID_BODY || ghostOverlaps[i]->getUserIndex() == CollisionObjectBullet::TYPE_AREA))
+ if (ghostOverlaps[i]->getUserIndex() == CollisionObjectBullet::TYPE_AREA) {
+ if (!static_cast<AreaBullet *>(ghostOverlaps[i]->getUserPointer())->is_monitorable())
+ continue;
+ } else if (ghostOverlaps[i]->getUserIndex() != CollisionObjectBullet::TYPE_RIGID_BODY)
continue;
otherObject = static_cast<RigidCollisionObjectBullet *>(ghostOverlaps[i]->getUserPointer());
@@ -1117,7 +1120,7 @@ bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btC
dispatcher->freeCollisionAlgorithm(algorithm);
if (contactPointResult.hasHit()) {
- r_delta_recover_movement += contactPointResult.m_pointNormalWorld * (contactPointResult.m_penetration_distance * p_recover_movement_scale);
+ r_delta_recover_movement += contactPointResult.m_pointNormalWorld * (contactPointResult.m_penetration_distance * -1 * p_recover_movement_scale);
if (r_recover_result) {
if (contactPointResult.m_penetration_distance < r_recover_result->penetration_distance) {
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index 42c3028f2c..897588385a 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -66,8 +66,169 @@ GDNativeLibrary::GDNativeLibrary() {
GDNativeLibrary::~GDNativeLibrary() {
}
+bool GDNativeLibrary::_set(const StringName &p_name, const Variant &p_property) {
+
+ String name = p_name;
+
+ if (name.begins_with("entry/")) {
+ String key = name.substr(6, name.length() - 6);
+
+ config_file->set_value("entry", key, p_property);
+
+ set_config_file(config_file);
+
+ return true;
+ }
+
+ if (name.begins_with("dependency/")) {
+ String key = name.substr(11, name.length() - 11);
+
+ config_file->set_value("dependencies", key, p_property);
+
+ set_config_file(config_file);
+
+ return true;
+ }
+
+ return false;
+}
+
+bool GDNativeLibrary::_get(const StringName &p_name, Variant &r_property) const {
+ String name = p_name;
+
+ if (name.begins_with("entry/")) {
+ String key = name.substr(6, name.length() - 6);
+
+ r_property = config_file->get_value("entry", key);
+
+ return true;
+ }
+
+ if (name.begins_with("dependency/")) {
+ String key = name.substr(11, name.length() - 11);
+
+ r_property = config_file->get_value("dependencies", key);
+
+ return true;
+ }
+
+ return false;
+}
+
+void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
+ // set entries
+ List<String> entry_key_list;
+
+ if (config_file->has_section("entry"))
+ config_file->get_section_keys("entry", &entry_key_list);
+
+ for (List<String>::Element *E = entry_key_list.front(); E; E = E->next()) {
+ String key = E->get();
+
+ PropertyInfo prop;
+
+ prop.type = Variant::STRING;
+ prop.name = "entry/" + key;
+
+ p_list->push_back(prop);
+ }
+
+ // set dependencies
+ List<String> dependency_key_list;
+
+ if (config_file->has_section("dependencies"))
+ config_file->get_section_keys("dependencies", &dependency_key_list);
+
+ for (List<String>::Element *E = dependency_key_list.front(); E; E = E->next()) {
+ String key = E->get();
+
+ PropertyInfo prop;
+
+ prop.type = Variant::STRING;
+ prop.name = "dependency/" + key;
+
+ p_list->push_back(prop);
+ }
+}
+
+void GDNativeLibrary::set_config_file(Ref<ConfigFile> p_config_file) {
+
+ set_singleton(p_config_file->get_value("general", "singleton", default_singleton));
+ set_load_once(p_config_file->get_value("general", "load_once", default_load_once));
+ set_symbol_prefix(p_config_file->get_value("general", "symbol_prefix", default_symbol_prefix));
+ set_reloadable(p_config_file->get_value("general", "reloadable", default_reloadable));
+
+ String entry_lib_path;
+ {
+
+ List<String> entry_keys;
+
+ if (p_config_file->has_section("entry"))
+ p_config_file->get_section_keys("entry", &entry_keys);
+
+ for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) {
+ String key = E->get();
+
+ Vector<String> tags = key.split(".");
+
+ bool skip = false;
+ for (int i = 0; i < tags.size(); i++) {
+ bool has_feature = OS::get_singleton()->has_feature(tags[i]);
+
+ if (!has_feature) {
+ skip = true;
+ break;
+ }
+ }
+
+ if (skip) {
+ continue;
+ }
+
+ entry_lib_path = p_config_file->get_value("entry", key);
+ break;
+ }
+ }
+
+ Vector<String> dependency_paths;
+ {
+
+ List<String> dependency_keys;
+
+ if (p_config_file->has_section("dependencies"))
+ p_config_file->get_section_keys("dependencies", &dependency_keys);
+
+ for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) {
+ String key = E->get();
+
+ Vector<String> tags = key.split(".");
+
+ bool skip = false;
+ for (int i = 0; i < tags.size(); i++) {
+ bool has_feature = OS::get_singleton()->has_feature(tags[i]);
+
+ if (!has_feature) {
+ skip = true;
+ break;
+ }
+ }
+
+ if (skip) {
+ continue;
+ }
+
+ dependency_paths = p_config_file->get_value("dependencies", key);
+ break;
+ }
+ }
+
+ current_library_path = entry_lib_path;
+ current_dependencies = dependency_paths;
+}
+
void GDNativeLibrary::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_config_file"), &GDNativeLibrary::get_config_file);
+ ClassDB::bind_method(D_METHOD("set_config_file", "config_file"), &GDNativeLibrary::set_config_file);
ClassDB::bind_method(D_METHOD("get_current_library_path"), &GDNativeLibrary::get_current_library_path);
ClassDB::bind_method(D_METHOD("get_current_dependencies"), &GDNativeLibrary::get_current_dependencies);
@@ -82,6 +243,8 @@ void GDNativeLibrary::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_symbol_prefix", "symbol_prefix"), &GDNativeLibrary::set_symbol_prefix);
ClassDB::bind_method(D_METHOD("set_reloadable", "reloadable"), &GDNativeLibrary::set_reloadable);
+ ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "config_file", PROPERTY_HINT_RESOURCE_TYPE, "ConfigFile"), "set_config_file", "get_config_file");
+
ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "load_once"), "set_load_once", "should_load_once");
ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "singleton"), "set_singleton", "is_singleton");
ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "symbol_prefix"), "set_symbol_prefix", "get_symbol_prefix");
@@ -337,73 +500,7 @@ RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_or
*r_error = err;
}
- lib->set_singleton(config->get_value("general", "singleton", default_singleton));
- lib->set_load_once(config->get_value("general", "load_once", default_load_once));
- lib->set_symbol_prefix(config->get_value("general", "symbol_prefix", default_symbol_prefix));
- lib->set_reloadable(config->get_value("general", "reloadable", default_reloadable));
-
- String entry_lib_path;
- {
-
- List<String> entry_keys;
- config->get_section_keys("entry", &entry_keys);
-
- for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) {
- String key = E->get();
-
- Vector<String> tags = key.split(".");
-
- bool skip = false;
- for (int i = 0; i < tags.size(); i++) {
- bool has_feature = OS::get_singleton()->has_feature(tags[i]);
-
- if (!has_feature) {
- skip = true;
- break;
- }
- }
-
- if (skip) {
- continue;
- }
-
- entry_lib_path = config->get_value("entry", key);
- break;
- }
- }
-
- Vector<String> dependency_paths;
- {
-
- List<String> dependency_keys;
- config->get_section_keys("dependencies", &dependency_keys);
-
- for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) {
- String key = E->get();
-
- Vector<String> tags = key.split(".");
-
- bool skip = false;
- for (int i = 0; i < tags.size(); i++) {
- bool has_feature = OS::get_singleton()->has_feature(tags[i]);
-
- if (!has_feature) {
- skip = true;
- break;
- }
- }
-
- if (skip) {
- continue;
- }
-
- dependency_paths = config->get_value("dependencies", key);
- break;
- }
- }
-
- lib->current_library_path = entry_lib_path;
- lib->current_dependencies = dependency_paths;
+ lib->set_config_file(config);
return lib;
}
diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h
index 3298ea950f..b17bb94f1c 100644
--- a/modules/gdnative/gdnative.h
+++ b/modules/gdnative/gdnative.h
@@ -66,8 +66,14 @@ public:
GDNativeLibrary();
~GDNativeLibrary();
+ virtual bool _set(const StringName &p_name, const Variant &p_property);
+ virtual bool _get(const StringName &p_name, Variant &r_property) const;
+ virtual void _get_property_list(List<PropertyInfo> *p_list) const;
+
_FORCE_INLINE_ Ref<ConfigFile> get_config_file() { return config_file; }
+ void set_config_file(Ref<ConfigFile> p_config_file);
+
// things that change per-platform
// so there are no setters for this
_FORCE_INLINE_ String get_current_library_path() const {
diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h
index 747328bc41..de47ec55cc 100644
--- a/modules/gdnative/include/nativescript/godot_nativescript.h
+++ b/modules/gdnative/include/nativescript/godot_nativescript.h
@@ -220,10 +220,10 @@ const void GDAPI *godot_nativescript_get_type_tag(const godot_object *p_object);
// instance binding API
typedef struct {
- void *(*alloc_instance_binding_data)(void *, godot_object *);
- void (*free_instance_binding_data)(void *, void *);
+ GDCALLINGCONV void *(*alloc_instance_binding_data)(void *, godot_object *);
+ GDCALLINGCONV void (*free_instance_binding_data)(void *, void *);
void *data;
- void (*free_func)(void *);
+ GDCALLINGCONV void (*free_func)(void *);
} godot_instance_binding_functions;
int GDAPI godot_nativescript_register_instance_binding_data_functions(godot_instance_binding_functions p_binding_functions);
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index 5806ee3f3f..ff31035036 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -881,6 +881,9 @@ NativeScriptInstance::~NativeScriptInstance() {
NativeScriptLanguage *NativeScriptLanguage::singleton;
void NativeScriptLanguage::_unload_stuff(bool p_reload) {
+
+ Map<String, Ref<GDNative> > erase_and_unload;
+
for (Map<String, Map<StringName, NativeScriptDesc> >::Element *L = library_classes.front(); L; L = L->next()) {
String lib_path = L->key();
@@ -916,18 +919,6 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) {
gdn = E->get();
}
- if (gdn.is_valid() && gdn->get_library().is_valid()) {
- Ref<GDNativeLibrary> lib = gdn->get_library();
- void *terminate_fn;
- Error err = gdn->get_symbol(lib->get_symbol_prefix() + _terminate_call_name, terminate_fn, true);
-
- if (err == OK) {
- void (*terminate)(void *) = (void (*)(void *))terminate_fn;
-
- terminate((void *)&lib_path);
- }
- }
-
for (Map<StringName, NativeScriptDesc>::Element *C = classes.front(); C; C = C->next()) {
// free property stuff first
@@ -952,6 +943,27 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) {
if (C->get().destroy_func.free_func)
C->get().destroy_func.free_func(C->get().destroy_func.method_data);
}
+
+ erase_and_unload.insert(lib_path, gdn);
+ }
+
+ for (Map<String, Ref<GDNative> >::Element *E = erase_and_unload.front(); E; E = E->next()) {
+ String lib_path = E->key();
+ Ref<GDNative> gdn = E->get();
+
+ library_classes.erase(lib_path);
+
+ if (gdn.is_valid() && gdn->get_library().is_valid()) {
+ Ref<GDNativeLibrary> lib = gdn->get_library();
+ void *terminate_fn;
+ Error err = gdn->get_symbol(lib->get_symbol_prefix() + _terminate_call_name, terminate_fn, true);
+
+ if (err == OK) {
+ void (*terminate)(void *) = (void (*)(void *))terminate_fn;
+
+ terminate((void *)&lib_path);
+ }
+ }
}
}
@@ -1363,6 +1375,7 @@ void NativeReloadNode::_notification(int p_what) {
MutexLock lock(NSL->mutex);
#endif
NSL->_unload_stuff(true);
+
for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
Ref<GDNative> gdn = L->get();
@@ -1376,7 +1389,6 @@ void NativeReloadNode::_notification(int p_what) {
}
gdn->terminate();
- NSL->library_classes.erase(L->key());
}
unloaded = true;
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 5f72dca866..87d8fe1bf5 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -2850,7 +2850,24 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
return OK;
}
} else {
- r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT;
+ /*
+ // Because get_integer_constant_enum and get_integer_constant dont work on @GlobalScope
+ // We cannot determine the exact nature of the identifier here
+ // Otherwise these codes would work
+ StringName enumName = ClassDB::get_integer_constant_enum("@GlobalScope", p_symbol, true);
+ if (enumName != NULL) {
+ r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_ENUM;
+ r_result.class_name = "@GlobalScope";
+ r_result.class_member = enumName;
+ return OK;
+ }
+ else {
+ r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT;
+ r_result.class_name = "@GlobalScope";
+ r_result.class_member = p_symbol;
+ return OK;
+ }*/
+ r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_TBD_GLOBALSCOPE;
r_result.class_name = "@GlobalScope";
r_result.class_member = p_symbol;
return OK;
@@ -2913,6 +2930,14 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
return OK;
}
+ StringName enumName = ClassDB::get_integer_constant_enum(t.obj_type, p_symbol, true);
+ if (enumName != StringName()) {
+ r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_ENUM;
+ r_result.class_name = t.obj_type;
+ r_result.class_member = enumName;
+ return OK;
+ }
+
bool success;
ClassDB::get_integer_constant(t.obj_type, p_symbol, &success);
if (success) {
diff --git a/modules/gdscript/gdscript_highlighter.cpp b/modules/gdscript/gdscript_highlighter.cpp
new file mode 100644
index 0000000000..5b8b652c29
--- /dev/null
+++ b/modules/gdscript/gdscript_highlighter.cpp
@@ -0,0 +1,278 @@
+/*************************************************************************/
+/* gdscript_highlighter.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "gdscript_highlighter.h"
+#include "scene/gui/text_edit.h"
+
+inline bool _is_symbol(CharType c) {
+
+ return is_symbol(c);
+}
+
+static bool _is_text_char(CharType c) {
+
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
+}
+
+static bool _is_whitespace(CharType c) {
+ return c == '\t' || c == ' ';
+}
+
+static bool _is_char(CharType c) {
+
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
+}
+
+static bool _is_number(CharType c) {
+ return (c >= '0' && c <= '9');
+}
+
+static bool _is_hex_symbol(CharType c) {
+ return ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
+}
+
+Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line) {
+ Map<int, TextEdit::HighlighterInfo> color_map;
+
+ bool prev_is_char = false;
+ bool prev_is_number = false;
+ bool in_keyword = false;
+ bool in_word = false;
+ bool in_function_name = false;
+ bool in_member_variable = false;
+ bool is_hex_notation = false;
+ Color keyword_color;
+ Color color;
+
+ int in_region = -1;
+ int deregion = 0;
+ for (int i = 0; i < p_line; i++) {
+ int ending_color_region = text_editor->_get_line_ending_color_region(i);
+ if (in_region == -1) {
+ in_region = ending_color_region;
+ } else if (in_region == ending_color_region) {
+ in_region = -1;
+ } else {
+ const Map<int, TextEdit::Text::ColorRegionInfo> &cri_map = text_editor->_get_line_color_region_info(i);
+ for (const Map<int, TextEdit::Text::ColorRegionInfo>::Element *E = cri_map.front(); E; E = E->next()) {
+ const TextEdit::Text::ColorRegionInfo &cri = E->get();
+ if (cri.region == in_region) {
+ in_region = -1;
+ }
+ }
+ }
+ }
+
+ const Map<int, TextEdit::Text::ColorRegionInfo> cri_map = text_editor->_get_line_color_region_info(p_line);
+ const String &str = text_editor->get_line(p_line);
+ Color prev_color;
+ for (int j = 0; j < str.length(); j++) {
+ TextEdit::HighlighterInfo highlighter_info;
+
+ if (deregion > 0) {
+ deregion--;
+ if (deregion == 0) {
+ in_region = -1;
+ }
+ }
+
+ if (deregion != 0) {
+ if (color != prev_color) {
+ prev_color = color;
+ highlighter_info.color = color;
+ color_map[j] = highlighter_info;
+ }
+ continue;
+ }
+
+ color = font_color;
+
+ bool is_char = _is_text_char(str[j]);
+ bool is_symbol = _is_symbol(str[j]);
+ bool is_number = _is_number(str[j]);
+
+ // allow ABCDEF in hex notation
+ if (is_hex_notation && (_is_hex_symbol(str[j]) || is_number)) {
+ is_number = true;
+ } else {
+ is_hex_notation = false;
+ }
+
+ // check for dot or underscore or 'x' for hex notation in floating point number
+ if ((str[j] == '.' || str[j] == 'x' || str[j] == '_') && !in_word && prev_is_number && !is_number) {
+ is_number = true;
+ is_symbol = false;
+ is_char = false;
+
+ if (str[j] == 'x' && str[j - 1] == '0') {
+ is_hex_notation = true;
+ }
+ }
+
+ if (!in_word && _is_char(str[j]) && !is_number) {
+ in_word = true;
+ }
+
+ if ((in_keyword || in_word) && !is_hex_notation) {
+ is_number = false;
+ }
+
+ if (is_symbol && str[j] != '.' && in_word) {
+ in_word = false;
+ }
+
+ if (is_symbol && cri_map.has(j)) {
+ const TextEdit::Text::ColorRegionInfo &cri = cri_map[j];
+
+ if (in_region == -1) {
+ if (!cri.end) {
+ in_region = cri.region;
+ }
+ } else {
+ TextEdit::ColorRegion cr = text_editor->_get_color_region(cri.region);
+ if (in_region == cri.region && !cr.line_only) { //ignore otherwise
+ if (cri.end || cr.eq) {
+ deregion = cr.eq ? cr.begin_key.length() : cr.end_key.length();
+ }
+ }
+ }
+ }
+
+ if (!is_char) {
+ in_keyword = false;
+ }
+
+ if (in_region == -1 && !in_keyword && is_char && !prev_is_char) {
+
+ int to = j;
+ while (to < str.length() && _is_text_char(str[to]))
+ to++;
+
+ String word = str.substr(j, to - j);
+ Color col = Color();
+ if (text_editor->has_keyword_color(word)) {
+ col = text_editor->get_keyword_color(word);
+ } else if (text_editor->has_member_color(word)) {
+ col = text_editor->get_member_color(word);
+ for (int k = j - 1; k >= 0; k--) {
+ if (str[k] == '.') {
+ col = Color(); //member indexing not allowed
+ break;
+ } else if (str[k] > 32) {
+ break;
+ }
+ }
+ }
+
+ if (col != Color()) {
+ in_keyword = true;
+ keyword_color = col;
+ }
+ }
+
+ if (!in_function_name && in_word && !in_keyword) {
+
+ int k = j;
+ while (k < str.length() && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') {
+ k++;
+ }
+
+ // check for space between name and bracket
+ while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) {
+ k++;
+ }
+
+ if (str[k] == '(') {
+ in_function_name = true;
+ }
+ }
+
+ if (!in_function_name && !in_member_variable && !in_keyword && !is_number && in_word) {
+ int k = j;
+ while (k > 0 && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') {
+ k--;
+ }
+
+ if (str[k] == '.') {
+ in_member_variable = true;
+ }
+ }
+
+ if (is_symbol) {
+ in_function_name = false;
+ in_member_variable = false;
+ }
+
+ if (in_region >= 0)
+ color = text_editor->_get_color_region(in_region).color;
+ else if (in_keyword)
+ color = keyword_color;
+ else if (in_member_variable)
+ color = member_color;
+ else if (in_function_name)
+ color = function_color;
+ else if (is_symbol)
+ color = symbol_color;
+ else if (is_number)
+ color = number_color;
+
+ prev_is_char = is_char;
+ prev_is_number = is_number;
+
+ if (color != prev_color) {
+ prev_color = color;
+ highlighter_info.color = color;
+ color_map[j] = highlighter_info;
+ }
+ }
+ return color_map;
+}
+
+String GDScriptSyntaxHighlighter::get_name() {
+ return "GDScript";
+}
+
+List<String> GDScriptSyntaxHighlighter::get_supported_languages() {
+ List<String> languages;
+ languages.push_back("GDScript");
+ return languages;
+}
+
+void GDScriptSyntaxHighlighter::_update_cache() {
+ font_color = text_editor->get_color("font_color");
+ symbol_color = text_editor->get_color("symbol_color");
+ function_color = text_editor->get_color("function_color");
+ number_color = text_editor->get_color("number_color");
+ member_color = text_editor->get_color("member_variable_color");
+}
+
+SyntaxHighlighter *GDScriptSyntaxHighlighter::create() {
+ return memnew(GDScriptSyntaxHighlighter);
+}
diff --git a/modules/gdscript/gdscript_highlighter.h b/modules/gdscript/gdscript_highlighter.h
new file mode 100644
index 0000000000..ef1bdd4103
--- /dev/null
+++ b/modules/gdscript/gdscript_highlighter.h
@@ -0,0 +1,56 @@
+/*************************************************************************/
+/* gdscript_highlighter.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef GDSCRIPT_HIGHLIGHTER_H
+#define GDSCRIPT_HIGHLIGHTER_H
+
+#include "scene/gui/text_edit.h"
+
+class GDScriptSyntaxHighlighter : public SyntaxHighlighter {
+private:
+ // colours
+ Color font_color;
+ Color symbol_color;
+ Color function_color;
+ Color built_in_type_color;
+ Color number_color;
+ Color member_color;
+
+public:
+ static SyntaxHighlighter *create();
+
+ virtual void _update_cache();
+ virtual Map<int, TextEdit::HighlighterInfo> _get_line_syntax_highlighting(int p_line);
+
+ virtual String get_name();
+ virtual List<String> get_supported_languages();
+};
+
+#endif // GDSCRIPT_HIGHLIGHTER_H
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index 95efcda80f..85c94c3596 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -31,6 +31,7 @@
#include "register_types.h"
#include "gdscript.h"
+#include "gdscript_highlighter.h"
#include "gdscript_tokenizer.h"
#include "io/file_access_encrypted.h"
#include "io/resource_loader.h"
@@ -92,6 +93,7 @@ void register_gdscript_types() {
ResourceSaver::add_resource_format_saver(resource_saver_gd);
#ifdef TOOLS_ENABLED
+ ScriptEditor::register_create_syntax_highlighter_function(GDScriptSyntaxHighlighter::create);
EditorNode::add_init_callback(_editor_init);
#endif
}
diff --git a/modules/mbedtls/stream_peer_mbed_tls.cpp b/modules/mbedtls/stream_peer_mbed_tls.cpp
index 4135eb40ff..a63e53ec1f 100755
--- a/modules/mbedtls/stream_peer_mbed_tls.cpp
+++ b/modules/mbedtls/stream_peer_mbed_tls.cpp
@@ -293,28 +293,10 @@ void StreamPeerMbedTLS::initialize_ssl() {
mbedtls_debug_set_threshold(1);
#endif
- String certs_path = GLOBAL_DEF("network/ssl/certificates", "");
- ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
-
- if (certs_path != "") {
-
- FileAccess *f = FileAccess::open(certs_path, FileAccess::READ);
- if (f) {
- PoolByteArray arr;
- int flen = f->get_len();
- arr.resize(flen + 1);
- {
- PoolByteArray::Write w = arr.write();
- f->get_buffer(w.ptr(), flen);
- w[flen] = 0; //end f string
- }
-
- memdelete(f);
-
- _load_certs(arr);
- print_line("Loaded certs from '" + certs_path);
- }
- }
+ PoolByteArray cert_array = StreamPeerSSL::get_project_cert_array();
+
+ if (cert_array.size() > 0)
+ _load_certs(cert_array);
available = true;
}
diff --git a/modules/mbedtls/stream_peer_mbed_tls.h b/modules/mbedtls/stream_peer_mbed_tls.h
index ce17614d85..2b96a194a1 100755
--- a/modules/mbedtls/stream_peer_mbed_tls.h
+++ b/modules/mbedtls/stream_peer_mbed_tls.h
@@ -32,8 +32,6 @@
#define STREAM_PEER_OPEN_SSL_H
#include "io/stream_peer_ssl.h"
-#include "os/file_access.h"
-#include "project_settings.h"
#include "mbedtls/config.h"
#include "mbedtls/ctr_drbg.h"
diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp
index ad07f043b2..2f2b5768db 100644
--- a/modules/mono/editor/godotsharp_builds.cpp
+++ b/modules/mono/editor/godotsharp_builds.cpp
@@ -525,11 +525,10 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) {
}
}
-GodotSharpBuilds::BuildProcess::BuildProcess(const MonoBuildInfo &p_build_info, GodotSharpBuild_ExitCallback p_callback) {
-
- build_info = p_build_info;
- build_tab = NULL;
- exit_callback = p_callback;
- exited = true;
- exit_code = -1;
+GodotSharpBuilds::BuildProcess::BuildProcess(const MonoBuildInfo &p_build_info, GodotSharpBuild_ExitCallback p_callback) :
+ build_info(p_build_info),
+ build_tab(NULL),
+ exit_callback(p_callback),
+ exited(true),
+ exit_code(-1) {
}
diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp
index 32aec2a3b5..f1cf0bcdf5 100644
--- a/modules/mono/editor/mono_bottom_panel.cpp
+++ b/modules/mono/editor/mono_bottom_panel.cpp
@@ -437,21 +437,16 @@ void MonoBuildTab::_bind_methods() {
ClassDB::bind_method("_issue_activated", &MonoBuildTab::_issue_activated);
}
-MonoBuildTab::MonoBuildTab(const MonoBuildInfo &p_build_info, const String &p_logs_dir) {
-
- build_info = p_build_info;
- logs_dir = p_logs_dir;
-
- build_exited = false;
-
- issues_list = memnew(ItemList);
+MonoBuildTab::MonoBuildTab(const MonoBuildInfo &p_build_info, const String &p_logs_dir) :
+ build_info(p_build_info),
+ logs_dir(p_logs_dir),
+ build_exited(false),
+ issues_list(memnew(ItemList)),
+ error_count(0),
+ warning_count(0),
+ errors_visible(true),
+ warnings_visible(true) {
issues_list->set_v_size_flags(SIZE_EXPAND_FILL);
issues_list->connect("item_activated", this, "_issue_activated");
add_child(issues_list);
-
- error_count = 0;
- warning_count = 0;
-
- errors_visible = true;
- warnings_visible = true;
}
diff --git a/modules/mono/glue/cs_files/Basis.cs b/modules/mono/glue/cs_files/Basis.cs
index 89b3e94c35..2e7e5404c4 100644
--- a/modules/mono/glue/cs_files/Basis.cs
+++ b/modules/mono/glue/cs_files/Basis.cs
@@ -49,20 +49,20 @@ namespace Godot
public Vector3 x
{
- get => GetAxis(0);
- set => SetAxis(0, value);
+ get { return GetAxis(0); }
+ set { SetAxis(0, value); }
}
public Vector3 y
{
- get => GetAxis(1);
- set => SetAxis(1, value);
+ get { return GetAxis(1); }
+ set { SetAxis(1, value); }
}
public Vector3 z
{
- get => GetAxis(2);
- set => SetAxis(2, value);
+ get { return GetAxis(2); }
+ set { SetAxis(2, value); }
}
private Vector3 _x;
diff --git a/modules/mono/glue/cs_files/Mathf.cs b/modules/mono/glue/cs_files/Mathf.cs
index 8b9c264d0d..adbcc855ef 100644
--- a/modules/mono/glue/cs_files/Mathf.cs
+++ b/modules/mono/glue/cs_files/Mathf.cs
@@ -257,5 +257,17 @@ namespace Godot
{
return (real_t)Math.Tanh(s);
}
+
+ public static int Wrap(int val, int min, int max)
+ {
+ int rng = max - min;
+ return min + ((((val - min) % rng) + rng) % rng);
+ }
+
+ public static real_t Wrap(real_t val, real_t min, real_t max)
+ {
+ real_t rng = max - min;
+ return min + (val - min) - (rng * Floor((val - min) / rng));
+ }
}
}
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index 58c6d73ab2..9e6307c0bf 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -261,14 +261,12 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
/* look for further theora headers */
while (theora_p && (theora_p < 3) && (ret = ogg_stream_packetout(&to, &op))) {
if (ret < 0) {
- fprintf(stderr, "Error parsing Theora stream headers; "
- "corrupt stream?\n");
+ fprintf(stderr, "Error parsing Theora stream headers; corrupt stream?\n");
clear();
return;
}
if (!th_decode_headerin(&ti, &tc, &ts, &op)) {
- fprintf(stderr, "Error parsing Theora stream headers; "
- "corrupt stream?\n");
+ fprintf(stderr, "Error parsing Theora stream headers; corrupt stream?\n");
clear();
return;
}
@@ -312,9 +310,15 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
td = th_decode_alloc(&ti, ts);
px_fmt = ti.pixel_fmt;
switch (ti.pixel_fmt) {
- case TH_PF_420: printf(" 4:2:0 video\n"); break;
- case TH_PF_422: printf(" 4:2:2 video\n"); break;
- case TH_PF_444: printf(" 4:4:4 video\n"); break;
+ case TH_PF_420:
+ //printf(" 4:2:0 video\n");
+ break;
+ case TH_PF_422:
+ //printf(" 4:2:2 video\n");
+ break;
+ case TH_PF_444:
+ //printf(" 4:4:4 video\n");
+ break;
case TH_PF_RSVD:
default:
printf(" video\n (UNKNOWN Chroma sampling!)\n");
@@ -519,7 +523,7 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
#else
if (file && /*!videobuf_ready && */ no_theora && theora_eos) {
#endif
- printf("video done, stopping\n");
+ //printf("video done, stopping\n");
stop();
return;
};
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 69503e631c..eb10c5e99f 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -3236,6 +3236,12 @@ void VisualScriptEditor::_member_option(int p_option) {
}
}
+void VisualScriptEditor::add_syntax_highlighter(SyntaxHighlighter *p_highlighter) {
+}
+
+void VisualScriptEditor::set_syntax_highlighter(SyntaxHighlighter *p_highlighter) {
+}
+
void VisualScriptEditor::_bind_methods() {
ClassDB::bind_method("_member_button", &VisualScriptEditor::_member_button);
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index 80bbf142d9..72b5e09222 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -246,6 +246,9 @@ protected:
static void _bind_methods();
public:
+ virtual void add_syntax_highlighter(SyntaxHighlighter *p_highlighter);
+ virtual void set_syntax_highlighter(SyntaxHighlighter *p_highlighter);
+
virtual void apply_code();
virtual Ref<Script> get_edited_script() const;
virtual Vector<String> get_functions();
diff --git a/modules/webm/libvpx/SCsub b/modules/webm/libvpx/SCsub
index 0ebafa022d..b09c232b3c 100644
--- a/modules/webm/libvpx/SCsub
+++ b/modules/webm/libvpx/SCsub
@@ -340,7 +340,7 @@ if webm_simd_optimizations == False:
env_libvpx.add_source_files(env.modules_sources, libvpx_sources)
if webm_cpu_x86:
- is_clang_or_gcc = ('gcc' in env["CC"]) or ('clang' in env["CC"])
+ is_clang_or_gcc = ('gcc' in env["CC"]) or ('clang' in env["CC"]) or ("OSXCROSS_ROOT" in os.environ)
env_libvpx_mmx = env_libvpx.Clone()
if cpu_bits == '32' and is_clang_or_gcc:
diff --git a/modules/websocket/lws_client.cpp b/modules/websocket/lws_client.cpp
index bebf342f8c..2220c9adf2 100644
--- a/modules/websocket/lws_client.cpp
+++ b/modules/websocket/lws_client.cpp
@@ -31,6 +31,7 @@
#include "lws_client.h"
#include "core/io/ip.h"
+#include "core/io/stream_peer_ssl.h"
Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocols) {
@@ -64,6 +65,9 @@ Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
info.uid = -1;
//info.ws_ping_pong_interval = 5;
info.user = _lws_ref;
+#if defined(LWS_OPENSSL_SUPPORT)
+ info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
+#endif
context = lws_create_context(&info);
if (context == NULL) {
@@ -87,7 +91,14 @@ Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
i.host = hbuf;
i.path = pbuf;
i.port = p_port;
- i.ssl_connection = p_ssl;
+
+ if (p_ssl) {
+ i.ssl_connection = LCCSCF_USE_SSL;
+ if (!verify_ssl)
+ i.ssl_connection |= LCCSCF_ALLOW_SELFSIGNED;
+ } else {
+ i.ssl_connection = 0;
+ }
lws_client_connect_via_info(&i);
return OK;
@@ -104,6 +115,13 @@ int LWSClient::_handle_cb(struct lws *wsi, enum lws_callback_reasons reason, voi
LWSPeer::PeerData *peer_data = (LWSPeer::PeerData *)user;
switch (reason) {
+ case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: {
+ PoolByteArray arr = StreamPeerSSL::get_project_cert_array();
+ if (arr.size() > 0)
+ SSL_CTX_add_client_CA((SSL_CTX *)user, d2i_X509(NULL, &arr.read()[0], arr.size()));
+ else if (verify_ssl)
+ WARN_PRINTS("No CA cert specified in project settings, SSL will not work");
+ } break;
case LWS_CALLBACK_CLIENT_ESTABLISHED:
peer->set_wsi(wsi);
diff --git a/modules/websocket/websocket_client.cpp b/modules/websocket/websocket_client.cpp
index 591d9510ce..7701163085 100644
--- a/modules/websocket/websocket_client.cpp
+++ b/modules/websocket/websocket_client.cpp
@@ -32,6 +32,8 @@
GDCINULL(WebSocketClient);
WebSocketClient::WebSocketClient() {
+
+ verify_ssl = true;
}
WebSocketClient::~WebSocketClient() {
@@ -72,6 +74,16 @@ Error WebSocketClient::connect_to_url(String p_url, PoolVector<String> p_protoco
return connect_to_host(host, path, port, ssl, p_protocols);
}
+void WebSocketClient::set_verify_ssl_enabled(bool p_verify_ssl) {
+
+ verify_ssl = p_verify_ssl;
+}
+
+bool WebSocketClient::is_verify_ssl_enabled() const {
+
+ return verify_ssl;
+}
+
bool WebSocketClient::is_server() const {
return false;
@@ -116,6 +128,10 @@ void WebSocketClient::_on_error() {
void WebSocketClient::_bind_methods() {
ClassDB::bind_method(D_METHOD("connect_to_url", "url", "protocols", "gd_mp_api"), &WebSocketClient::connect_to_url, DEFVAL(PoolVector<String>()), DEFVAL(false));
ClassDB::bind_method(D_METHOD("disconnect_from_host"), &WebSocketClient::disconnect_from_host);
+ ClassDB::bind_method(D_METHOD("set_verify_ssl_enabled", "enabled"), &WebSocketClient::set_verify_ssl_enabled);
+ ClassDB::bind_method(D_METHOD("is_verify_ssl_enabled"), &WebSocketClient::is_verify_ssl_enabled);
+
+ ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "verify_ssl", PROPERTY_HINT_NONE, "", 0), "set_verify_ssl_enabled", "is_verify_ssl_enabled");
ADD_SIGNAL(MethodInfo("data_received"));
ADD_SIGNAL(MethodInfo("connection_established", PropertyInfo(Variant::STRING, "protocol")));
diff --git a/modules/websocket/websocket_client.h b/modules/websocket/websocket_client.h
index 5c863559bc..6165f37d40 100644
--- a/modules/websocket/websocket_client.h
+++ b/modules/websocket/websocket_client.h
@@ -41,12 +41,16 @@ class WebSocketClient : public WebSocketMultiplayerPeer {
protected:
Ref<WebSocketPeer> _peer;
+ bool verify_ssl;
static void _bind_methods();
public:
Error connect_to_url(String p_url, PoolVector<String> p_protocols = PoolVector<String>(), bool gd_mp_api = false);
+ void set_verify_ssl_enabled(bool p_verify_ssl);
+ bool is_verify_ssl_enabled() const;
+
virtual void poll() = 0;
virtual Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocol = PoolVector<String>()) = 0;
virtual void disconnect_from_host() = 0;