-Support for changing fonts
-Detect when free() might crash the project and throw error -fixed 2D Bounce in physics (3d still broken) -renamed “on_top” property to “behind_parent”, which makes more sense, old on_top remains there for compatibility but is invisible. -large amount of fixes
This commit is contained in:
parent
35b84d2c85
commit
9f33134c93
|
@ -246,6 +246,12 @@ Error _OS::kill(int p_pid) {
|
|||
return OS::get_singleton()->kill(p_pid);
|
||||
}
|
||||
|
||||
int _OS::get_process_ID() const {
|
||||
|
||||
return OS::get_singleton()->get_process_ID();
|
||||
};
|
||||
|
||||
|
||||
bool _OS::has_environment(const String& p_var) const {
|
||||
|
||||
return OS::get_singleton()->has_environment(p_var);
|
||||
|
@ -561,6 +567,7 @@ void _OS::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("execute","path","arguments","blocking"),&_OS::execute);
|
||||
ObjectTypeDB::bind_method(_MD("kill","pid"),&_OS::kill);
|
||||
ObjectTypeDB::bind_method(_MD("shell_open","uri"),&_OS::shell_open);
|
||||
ObjectTypeDB::bind_method(_MD("get_process_ID"),&_OS::get_process_ID);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_environment","environment"),&_OS::get_environment);
|
||||
ObjectTypeDB::bind_method(_MD("has_environment","environment"),&_OS::has_environment);
|
||||
|
|
|
@ -117,6 +117,8 @@ public:
|
|||
Error kill(int p_pid);
|
||||
Error shell_open(String p_uri);
|
||||
|
||||
int get_process_ID() const;
|
||||
|
||||
bool has_environment(const String& p_var) const;
|
||||
String get_environment(const String& p_var) const;
|
||||
|
||||
|
|
|
@ -949,6 +949,7 @@ String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) {
|
|||
|
||||
} else if (header[0]!='R' || header[1]!='S' || header[2]!='R' || header[3]!='C') {
|
||||
//not normal
|
||||
error=ERR_FILE_UNRECOGNIZED;
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
|
@ -378,11 +378,12 @@ void MessageQueue::flush() {
|
|||
}
|
||||
|
||||
}
|
||||
message->~Message();
|
||||
|
||||
read_pos+=sizeof(Message);
|
||||
if (message->type!=TYPE_NOTIFICATION)
|
||||
read_pos+=sizeof(Variant)*message->args;
|
||||
message->~Message();
|
||||
|
||||
_THREAD_SAFE_UNLOCK_
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,30 @@
|
|||
#include "message_queue.h"
|
||||
#include "core_string_names.h"
|
||||
#include "translation.h"
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
struct _ObjectDebugLock {
|
||||
|
||||
Object *obj;
|
||||
|
||||
_ObjectDebugLock(Object *p_obj) {
|
||||
obj=p_obj;
|
||||
obj->_lock_index.ref();
|
||||
}
|
||||
~_ObjectDebugLock() {
|
||||
obj->_lock_index.unref();
|
||||
}
|
||||
};
|
||||
|
||||
#define OBJ_DEBUG_LOCK _ObjectDebugLock _debug_lock(this);
|
||||
|
||||
#else
|
||||
|
||||
#define OBJ_DEBUG_LOCK
|
||||
|
||||
#endif
|
||||
|
||||
Array convert_property_list(const List<PropertyInfo> * p_list) {
|
||||
|
||||
Array va;
|
||||
|
@ -562,13 +586,22 @@ void Object::call_multilevel(const StringName& p_method,const Variant** p_args,i
|
|||
ERR_FAIL();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (_lock_index.get()>1) {
|
||||
ERR_EXPLAIN("Object is locked and can't be freed.");
|
||||
ERR_FAIL();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
//must be here, must be before everything,
|
||||
memdelete(this);
|
||||
return;
|
||||
}
|
||||
|
||||
//Variant ret;
|
||||
OBJ_DEBUG_LOCK
|
||||
|
||||
Variant::CallError error;
|
||||
|
||||
|
@ -594,6 +627,7 @@ void Object::call_multilevel_reversed(const StringName& p_method,const Variant**
|
|||
MethodBind *method=ObjectTypeDB::get_method(get_type_name(),p_method);
|
||||
|
||||
Variant::CallError error;
|
||||
OBJ_DEBUG_LOCK
|
||||
|
||||
if (method) {
|
||||
|
||||
|
@ -813,6 +847,15 @@ Variant Object::call(const StringName& p_method,const Variant** p_args,int p_arg
|
|||
ERR_EXPLAIN("Can't 'free' a reference.");
|
||||
ERR_FAIL_V(Variant());
|
||||
}
|
||||
|
||||
if (_lock_index.get()>1) {
|
||||
r_error.argument=0;
|
||||
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
|
||||
ERR_EXPLAIN("Object is locked and can't be freed.");
|
||||
ERR_FAIL_V(Variant());
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
//must be here, must be before everything,
|
||||
memdelete(this);
|
||||
|
@ -821,7 +864,7 @@ Variant Object::call(const StringName& p_method,const Variant** p_args,int p_arg
|
|||
}
|
||||
|
||||
Variant ret;
|
||||
|
||||
OBJ_DEBUG_LOCK
|
||||
if (script_instance) {
|
||||
ret = script_instance->call(p_method,p_args,p_argcount,r_error);
|
||||
//force jumptable
|
||||
|
@ -902,7 +945,7 @@ void Object::set_script(const RefPtr& p_script) {
|
|||
Ref<Script> s(script);
|
||||
|
||||
if (!s.is_null() && s->can_instance() ) {
|
||||
|
||||
OBJ_DEBUG_LOCK
|
||||
script_instance = s->instance_create(this);
|
||||
|
||||
}
|
||||
|
@ -1066,6 +1109,8 @@ void Object::emit_signal(const StringName& p_name,VARIANT_ARG_DECLARE) {
|
|||
|
||||
int ssize = slot_map.size();
|
||||
|
||||
OBJ_DEBUG_LOCK
|
||||
|
||||
for(int i=0;i<ssize;i++) {
|
||||
|
||||
const Connection &c = slot_map.getv(i).conn;
|
||||
|
@ -1536,6 +1581,11 @@ Object::Object() {
|
|||
_edited=false;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
_lock_index.init(1);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -331,7 +331,9 @@ public:
|
|||
Connection(const Variant& p_variant);
|
||||
};
|
||||
private:
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
friend class _ObjectDebugLock;
|
||||
#endif
|
||||
friend bool predelete_handler(Object*);
|
||||
friend void postinitialize_handler(Object*);
|
||||
|
||||
|
@ -365,7 +367,9 @@ friend void postinitialize_handler(Object*);
|
|||
|
||||
HashMap< StringName, Signal, StringNameHasher> signal_map;
|
||||
List<Connection> connections;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
SafeRefCount _lock_index;
|
||||
#endif
|
||||
bool _block_signals;
|
||||
int _predelete_ok;
|
||||
Set<Object*> change_receptors;
|
||||
|
|
|
@ -124,6 +124,11 @@ String OS::get_executable_path() const {
|
|||
return _execpath;
|
||||
}
|
||||
|
||||
int OS::get_process_ID() const {
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
uint64_t OS::get_frames_drawn() {
|
||||
|
||||
return frames_drawn;
|
||||
|
|
|
@ -162,6 +162,7 @@ public:
|
|||
virtual String get_executable_path() const;
|
||||
virtual Error execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id=NULL,String* r_pipe=NULL,int *r_exitcode=NULL)=0;
|
||||
virtual Error kill(const ProcessID& p_pid)=0;
|
||||
virtual int get_process_ID() const;
|
||||
|
||||
virtual Error shell_open(String p_uri);
|
||||
virtual Error set_cwd(const String& p_cwd);
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<resource_file type="PackedScene" subresource_count="24" version="1.0" version_name="Godot Engine v1.0.3917-beta1">
|
||||
<ext_resource path="res://robot_demo.*" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://osb_jump.*" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://player.*" type="Script"></ext_resource>
|
||||
<ext_resource path="res://osb_right.*" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://sound_coin.*" type="Sample"></ext_resource>
|
||||
<ext_resource path="res://sound_jump.*" type="Sample"></ext_resource>
|
||||
<ext_resource path="res://sound_shoot.*" type="Sample"></ext_resource>
|
||||
<ext_resource path="res://bullet.*" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://osb_fire.*" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://osb_left.*" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://osb_jump.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://bullet.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://osb_right.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://sound_coin.wav" type="Sample"></ext_resource>
|
||||
<ext_resource path="res://sound_shoot.wav" type="Sample"></ext_resource>
|
||||
<ext_resource path="res://osb_fire.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://robot_demo.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://osb_left.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://player.gd" type="Script"></ext_resource>
|
||||
<ext_resource path="res://sound_jump.wav" type="Sample"></ext_resource>
|
||||
<resource type="RayShape2D" path="local://1">
|
||||
<real name="custom_solver_bias"> 0.5 </real>
|
||||
<real name="length"> 20 </real>
|
||||
|
@ -50,30 +50,6 @@
|
|||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://4">
|
||||
<string name="resource/name"> "jumping" </string>
|
||||
<real name="length"> 0.5 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="3"> 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="3" shared="false">
|
||||
<int> 23 </int>
|
||||
<int> 24 </int>
|
||||
<int> 23 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="3"> 0, 0.25, 0.5 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://5">
|
||||
<string name="resource/name"> "run" </string>
|
||||
<real name="length"> 1.25 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
|
@ -100,144 +76,7 @@
|
|||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://6">
|
||||
<string name="resource/name"> "run_weapon" </string>
|
||||
<real name="length"> 1.25 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="6"> 1, 1, 1, 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="6" shared="false">
|
||||
<int> 5 </int>
|
||||
<int> 6 </int>
|
||||
<int> 7 </int>
|
||||
<int> 8 </int>
|
||||
<int> 9 </int>
|
||||
<int> 5 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://7">
|
||||
<string name="resource/name"> "falling" </string>
|
||||
<real name="length"> 0.01 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 21 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://8">
|
||||
<string name="resource/name"> "falling_weapon" </string>
|
||||
<real name="length"> 0.5 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 26 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://9">
|
||||
<string name="resource/name"> "idle_weapon" </string>
|
||||
<real name="length"> 0.5 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 25 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://10">
|
||||
<string name="resource/name"> "jumping_weapon" </string>
|
||||
<real name="length"> 0.5 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 26 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://11">
|
||||
<string name="resource/name"> "crouch" </string>
|
||||
<real name="length"> 0.01 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 22 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://12">
|
||||
<resource type="Animation" path="local://5">
|
||||
<string name="resource/name"> "run_gun_fire" </string>
|
||||
<real name="length"> 1.25 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
|
@ -263,6 +102,167 @@
|
|||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://6">
|
||||
<string name="resource/name"> "jumping_weapon" </string>
|
||||
<real name="length"> 0.5 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 26 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://7">
|
||||
<string name="resource/name"> "crouch" </string>
|
||||
<real name="length"> 0.01 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 22 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://8">
|
||||
<string name="resource/name"> "jumping" </string>
|
||||
<real name="length"> 0.5 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="3"> 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="3" shared="false">
|
||||
<int> 23 </int>
|
||||
<int> 24 </int>
|
||||
<int> 23 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="3"> 0, 0.25, 0.5 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://9">
|
||||
<string name="resource/name"> "run_weapon" </string>
|
||||
<real name="length"> 1.25 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="6"> 1, 1, 1, 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="6" shared="false">
|
||||
<int> 5 </int>
|
||||
<int> 6 </int>
|
||||
<int> 7 </int>
|
||||
<int> 8 </int>
|
||||
<int> 9 </int>
|
||||
<int> 5 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://10">
|
||||
<string name="resource/name"> "idle_weapon" </string>
|
||||
<real name="length"> 0.5 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 25 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://11">
|
||||
<string name="resource/name"> "falling_weapon" </string>
|
||||
<real name="length"> 0.5 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 26 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://12">
|
||||
<string name="resource/name"> "falling" </string>
|
||||
<real name="length"> 0.01 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 21 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="SampleLibrary" path="local://13">
|
||||
<dictionary name="samples/jump" shared="false">
|
||||
|
@ -271,7 +271,7 @@
|
|||
<string> "pitch" </string>
|
||||
<real> 1 </real>
|
||||
<string> "sample" </string>
|
||||
<resource resource_type="Sample" path="res://sound_jump.*"> </resource>
|
||||
<resource resource_type="Sample" path="res://sound_jump.wav"> </resource>
|
||||
</dictionary>
|
||||
<dictionary name="samples/shoot" shared="false">
|
||||
<string> "db" </string>
|
||||
|
@ -279,7 +279,7 @@
|
|||
<string> "pitch" </string>
|
||||
<real> 1 </real>
|
||||
<string> "sample" </string>
|
||||
<resource resource_type="Sample" path="res://sound_shoot.*"> </resource>
|
||||
<resource resource_type="Sample" path="res://sound_shoot.wav"> </resource>
|
||||
</dictionary>
|
||||
<dictionary name="samples/coin" shared="false">
|
||||
<string> "db" </string>
|
||||
|
@ -287,7 +287,7 @@
|
|||
<string> "pitch" </string>
|
||||
<real> 1 </real>
|
||||
<string> "sample" </string>
|
||||
<resource resource_type="Sample" path="res://sound_coin.*"> </resource>
|
||||
<resource resource_type="Sample" path="res://sound_coin.wav"> </resource>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
|
@ -300,7 +300,7 @@
|
|||
<string> "visibility/visible" </string>
|
||||
<string> "visibility/opacity" </string>
|
||||
<string> "visibility/self_opacity" </string>
|
||||
<string> "visibility/on_top" </string>
|
||||
<string> "visibility/behind_parent" </string>
|
||||
<string> "transform/pos" </string>
|
||||
<string> "transform/rot" </string>
|
||||
<string> "transform/scale" </string>
|
||||
|
@ -396,15 +396,15 @@
|
|||
<string> "playback/default_blend_time" </string>
|
||||
<string> "root/root" </string>
|
||||
<string> "anims/idle" </string>
|
||||
<string> "anims/jumping" </string>
|
||||
<string> "anims/run" </string>
|
||||
<string> "anims/run_weapon" </string>
|
||||
<string> "anims/falling" </string>
|
||||
<string> "anims/falling_weapon" </string>
|
||||
<string> "anims/idle_weapon" </string>
|
||||
<string> "anims/standing_weapon_ready" </string>
|
||||
<string> "anims/jumping_weapon" </string>
|
||||
<string> "anims/crouch" </string>
|
||||
<string> "anims/standing_weapon_ready" </string>
|
||||
<string> "anims/jumping" </string>
|
||||
<string> "anims/run_weapon" </string>
|
||||
<string> "anims/idle_weapon" </string>
|
||||
<string> "anims/falling_weapon" </string>
|
||||
<string> "anims/falling" </string>
|
||||
<string> "playback/active" </string>
|
||||
<string> "playback/speed" </string>
|
||||
<string> "blend_times" </string>
|
||||
|
@ -476,18 +476,19 @@
|
|||
<array len="71" shared="false">
|
||||
<bool> True </bool>
|
||||
<real> 1 </real>
|
||||
<bool> False </bool>
|
||||
<vector2> 0, 0 </vector2>
|
||||
<real> 0 </real>
|
||||
<vector2> 1, 1 </vector2>
|
||||
<int> 2 </int>
|
||||
<resource resource_type="Shape2D" path="local://1"> </resource>
|
||||
<matrix32> 1, -0, 0, 1.76469, 0.291992, -12.1587 </matrix32>
|
||||
<bool> False </bool>
|
||||
<resource resource_type="Shape2D" path="local://2"> </resource>
|
||||
<matrix32> 1, -0, 0, 1, 0, 0 </matrix32>
|
||||
<real> 3 </real>
|
||||
<int> 0 </int>
|
||||
<int> 3 </int>
|
||||
<resource resource_type="Script" path="res://player.*"> </resource>
|
||||
<resource resource_type="Script" path="res://player.gd"> </resource>
|
||||
<dictionary shared="false">
|
||||
<string> "__editor_plugin_states__" </string>
|
||||
<dictionary shared="false">
|
||||
|
@ -507,7 +508,7 @@
|
|||
<string> "zoom" </string>
|
||||
<real> 2.272073 </real>
|
||||
<string> "ofs" </string>
|
||||
<vector2> -125.17, -137.776 </vector2>
|
||||
<vector2> -181.946, -86.2812 </vector2>
|
||||
</dictionary>
|
||||
<string> "3D" </string>
|
||||
<dictionary shared="false">
|
||||
|
@ -594,20 +595,20 @@
|
|||
<int> 0 </int>
|
||||
</dictionary>
|
||||
<string> "__editor_plugin_screen__" </string>
|
||||
<string> "2D" </string>
|
||||
<string> "3D" </string>
|
||||
</dictionary>
|
||||
<resource resource_type="Texture" path="res://robot_demo.*"> </resource>
|
||||
<resource resource_type="Texture" path="res://robot_demo.png"> </resource>
|
||||
<int> 16 </int>
|
||||
<int> 1 </int>
|
||||
<color> 1, 1, 1, 1 </color>
|
||||
<rect2> 0, 0, 0, 0 </rect2>
|
||||
<real> 0.363636 </real>
|
||||
<int> 1 </int>
|
||||
<vector2> 20.7312, 3.21187 </vector2>
|
||||
<real> 83.450417 </real>
|
||||
<int> 4 </int>
|
||||
<real> 0.3 </real>
|
||||
<real> 0.1 </real>
|
||||
<resource resource_type="Texture" path="res://bullet.*"> </resource>
|
||||
<resource resource_type="Texture" path="res://bullet.png"> </resource>
|
||||
<real> 180 </real>
|
||||
<real> 20 </real>
|
||||
<real> 9.8 </real>
|
||||
|
@ -630,7 +631,6 @@
|
|||
<array len="0" shared="false">
|
||||
</array>
|
||||
<string> "" </string>
|
||||
<int> 0 </int>
|
||||
<int> 10000000 </int>
|
||||
<real> 0.2 </real>
|
||||
<vector2> 31.2428, 4.08784 </vector2>
|
||||
|
@ -641,20 +641,20 @@
|
|||
<vector2_array len="3"> -0.138023, 16.5036, -19.902, -24.8691, 19.3625, -24.6056 </vector2_array>
|
||||
<vector2> 27.7593, 360.87 </vector2>
|
||||
<vector2> 1.49157, 1.46265 </vector2>
|
||||
<resource resource_type="Texture" path="res://osb_left.*"> </resource>
|
||||
<resource resource_type="Texture" path="res://osb_left.png"> </resource>
|
||||
<resource name=""></resource> <string> "move_left" </string>
|
||||
<vector2> 121.542, 361.415 </vector2>
|
||||
<resource resource_type="Texture" path="res://osb_right.*"> </resource>
|
||||
<resource resource_type="Texture" path="res://osb_right.png"> </resource>
|
||||
<string> "move_right" </string>
|
||||
<vector2> 666.224, 359.02 </vector2>
|
||||
<resource resource_type="Texture" path="res://osb_jump.*"> </resource>
|
||||
<resource resource_type="Texture" path="res://osb_jump.png"> </resource>
|
||||
<string> "jump" </string>
|
||||
<vector2> 668.073, 262.788 </vector2>
|
||||
<resource resource_type="Texture" path="res://osb_fire.*"> </resource>
|
||||
<resource resource_type="Texture" path="res://osb_fire.png"> </resource>
|
||||
<string> "shoot" </string>
|
||||
</array>
|
||||
<string> "nodes" </string>
|
||||
<int_array len="572"> -1, -1, 1, 0, -1, 28, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 8, 13, 9, 14, 10, 15, 8, 16, 5, 17, 11, 18, 3, 19, 3, 20, 0, 21, 8, 22, 12, 23, 8, 24, 0, 25, 0, 26, 2, 27, 3, 28, 13, 29, 14, 0, 0, 0, 31, 30, -1, 18, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 32, 15, 33, 0, 34, 2, 35, 8, 36, 8, 37, 5, 38, 16, 39, 17, 40, 18, 41, 8, 42, 19, 0, 1, 0, 44, 43, -1, 57, 2, 0, 3, 1, 4, 20, 5, 0, 45, 17, 6, 21, 7, 22, 8, 4, 46, 23, 47, 24, 48, 1, 49, 3, 50, 24, 51, 8, 52, 2, 53, 2, 54, 8, 55, 25, 56, 8, 57, 8, 58, 26, 59, 3, 60, 27, 61, 28, 62, 1, 63, 3, 64, 3, 65, 29, 66, 3, 67, 3, 68, 3, 69, 30, 70, 30, 71, 3, 72, 3, 73, 3, 74, 3, 75, 30, 76, 3, 77, 3, 78, 3, 79, 3, 80, 3, 81, 3, 82, 3, 83, 3, 84, 3, 85, 5, 86, 3, 87, 18, 88, 1, 89, 31, 90, 1, 91, 32, 92, 1, 93, 33, 94, 34, 0, 0, 0, 96, 95, -1, 17, 97, 17, 98, 3, 99, 35, 100, 36, 101, 37, 102, 38, 103, 39, 104, 40, 105, 41, 106, 42, 107, 43, 108, 44, 109, 45, 110, 0, 111, 30, 112, 46, 113, 47, 0, 0, 0, 115, 114, -1, 22, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 33, 0, 116, 8, 117, 0, 118, 3, 119, 4, 120, 48, 121, 48, 122, 49, 123, 49, 124, 0, 125, 0, 126, 50, 127, 50, 128, 50, 129, 50, 0, 0, 0, 131, 130, -1, 7, 2, 0, 3, 1, 4, 1, 5, 0, 6, 51, 7, 3, 8, 4, 0, 0, 0, 132, 132, -1, 9, 2, 0, 3, 1, 4, 1, 5, 0, 6, 52, 7, 3, 8, 53, 133, 6, 134, 8, 0, 0, 0, 136, 135, -1, 14, 137, 12, 138, 54, 139, 3, 140, 1, 141, 3, 142, 3, 143, 3, 144, 55, 145, 55, 146, 55, 147, 55, 148, 5, 149, 3, 150, 3, 0, 0, 0, 151, 151, -1, 9, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 152, 48, 153, 56, 0, 0, 0, 155, 154, -1, 4, 156, 48, 34, 2, 157, 3, 158, 4, 0, 9, 0, 160, 159, -1, 13, 2, 0, 3, 1, 4, 1, 5, 0, 6, 57, 7, 3, 8, 58, 161, 59, 162, 60, 163, 60, 164, 0, 165, 61, 166, 17, 0, 9, 0, 160, 167, -1, 13, 2, 0, 3, 1, 4, 1, 5, 0, 6, 62, 7, 3, 8, 58, 161, 63, 162, 60, 163, 60, 164, 0, 165, 64, 166, 17, 0, 9, 0, 160, 168, -1, 13, 2, 0, 3, 1, 4, 1, 5, 0, 6, 65, 7, 3, 8, 58, 161, 66, 162, 60, 163, 60, 164, 8, 165, 67, 166, 17, 0, 9, 0, 160, 169, -1, 13, 2, 0, 3, 1, 4, 1, 5, 0, 6, 68, 7, 3, 8, 58, 161, 69, 162, 60, 163, 60, 164, 8, 165, 70, 166, 17, 0 </int_array>
|
||||
<int_array len="572"> -1, -1, 1, 0, -1, 28, 2, 0, 3, 1, 4, 1, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 7, 11, 8, 12, 2, 13, 9, 14, 10, 15, 2, 16, 6, 17, 11, 18, 4, 19, 4, 20, 0, 21, 12, 22, 13, 23, 2, 24, 0, 25, 0, 26, 3, 27, 4, 28, 14, 29, 15, 0, 0, 0, 31, 30, -1, 18, 2, 0, 3, 1, 4, 1, 5, 2, 6, 3, 7, 4, 8, 5, 32, 16, 33, 0, 34, 3, 35, 2, 36, 2, 37, 6, 38, 17, 39, 12, 40, 18, 41, 2, 42, 19, 0, 1, 0, 44, 43, -1, 57, 2, 0, 3, 1, 4, 20, 5, 2, 45, 21, 6, 22, 7, 23, 8, 5, 46, 24, 47, 25, 48, 1, 49, 4, 50, 25, 51, 2, 52, 3, 53, 3, 54, 2, 55, 26, 56, 2, 57, 2, 58, 27, 59, 4, 60, 28, 61, 29, 62, 1, 63, 4, 64, 4, 65, 30, 66, 4, 67, 4, 68, 4, 69, 31, 70, 31, 71, 4, 72, 4, 73, 4, 74, 4, 75, 31, 76, 4, 77, 4, 78, 4, 79, 4, 80, 4, 81, 4, 82, 4, 83, 4, 84, 4, 85, 6, 86, 4, 87, 18, 88, 1, 89, 32, 90, 1, 91, 33, 92, 1, 93, 34, 94, 35, 0, 0, 0, 96, 95, -1, 17, 97, 21, 98, 4, 99, 36, 100, 37, 101, 38, 102, 39, 103, 40, 104, 41, 105, 42, 106, 43, 107, 44, 108, 45, 109, 46, 110, 0, 111, 31, 112, 47, 113, 48, 0, 0, 0, 115, 114, -1, 22, 2, 0, 3, 1, 4, 1, 5, 2, 6, 3, 7, 4, 8, 5, 33, 0, 116, 2, 117, 0, 118, 4, 119, 5, 120, 12, 121, 12, 122, 49, 123, 49, 124, 0, 125, 0, 126, 50, 127, 50, 128, 50, 129, 50, 0, 0, 0, 131, 130, -1, 7, 2, 0, 3, 1, 4, 1, 5, 2, 6, 51, 7, 4, 8, 5, 0, 0, 0, 132, 132, -1, 9, 2, 0, 3, 1, 4, 1, 5, 2, 6, 52, 7, 4, 8, 53, 133, 7, 134, 2, 0, 0, 0, 136, 135, -1, 14, 137, 13, 138, 54, 139, 4, 140, 1, 141, 4, 142, 4, 143, 4, 144, 55, 145, 55, 146, 55, 147, 55, 148, 6, 149, 4, 150, 4, 0, 0, 0, 151, 151, -1, 9, 2, 0, 3, 1, 4, 1, 5, 2, 6, 3, 7, 4, 8, 5, 152, 12, 153, 56, 0, 0, 0, 155, 154, -1, 4, 156, 12, 34, 3, 157, 4, 158, 5, 0, 9, 0, 160, 159, -1, 13, 2, 0, 3, 1, 4, 1, 5, 2, 6, 57, 7, 4, 8, 58, 161, 59, 162, 60, 163, 60, 164, 0, 165, 61, 166, 21, 0, 9, 0, 160, 167, -1, 13, 2, 0, 3, 1, 4, 1, 5, 2, 6, 62, 7, 4, 8, 58, 161, 63, 162, 60, 163, 60, 164, 0, 165, 64, 166, 21, 0, 9, 0, 160, 168, -1, 13, 2, 0, 3, 1, 4, 1, 5, 2, 6, 65, 7, 4, 8, 58, 161, 66, 162, 60, 163, 60, 164, 2, 165, 67, 166, 21, 0, 9, 0, 160, 169, -1, 13, 2, 0, 3, 1, 4, 1, 5, 2, 6, 68, 7, 4, 8, 58, 161, 69, 162, 60, 163, 60, 164, 2, 165, 70, 166, 21, 0 </int_array>
|
||||
<string> "conns" </string>
|
||||
<int_array len="0"> </int_array>
|
||||
</dictionary>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -333,6 +333,12 @@ Error OS_Unix::kill(const ProcessID& p_pid) {
|
|||
return ret?ERR_INVALID_PARAMETER:OK;
|
||||
}
|
||||
|
||||
int OS_Unix::get_process_ID() const {
|
||||
|
||||
return getpid();
|
||||
};
|
||||
|
||||
|
||||
bool OS_Unix::has_environment(const String& p_var) const {
|
||||
|
||||
return getenv(p_var.utf8().get_data())!=NULL;
|
||||
|
|
|
@ -98,6 +98,7 @@ public:
|
|||
|
||||
virtual Error execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id=NULL,String* r_pipe=NULL,int *r_exitcode=NULL);
|
||||
virtual Error kill(const ProcessID& p_pid);
|
||||
virtual int get_process_ID() const;
|
||||
|
||||
virtual bool has_environment(const String& p_var) const;
|
||||
virtual String get_environment(const String& p_var) const;
|
||||
|
|
|
@ -10,7 +10,6 @@ env.modules_sources=[
|
|||
#env.add_source_files(env.modules_sources,"*.cpp")
|
||||
Export('env')
|
||||
|
||||
|
||||
for x in env.module_list:
|
||||
if (x in env.disabled_modules):
|
||||
continue
|
||||
|
|
|
@ -1095,7 +1095,7 @@ MethodInfo GDFunctions::get_info(Function p_func) {
|
|||
return mi;
|
||||
} break;
|
||||
case MATH_RAND: {
|
||||
MethodInfo mi("rand");
|
||||
MethodInfo mi("randi");
|
||||
mi.return_val.type=Variant::INT;
|
||||
return mi;
|
||||
} break;
|
||||
|
|
|
@ -635,6 +635,19 @@ Variant GDFunction::call(GDInstance *p_instance,const Variant **p_args, int p_ar
|
|||
err.argument-=1;
|
||||
}
|
||||
}
|
||||
} if (methodstr=="free") {
|
||||
|
||||
if (err.error==Variant::CallError::CALL_ERROR_INVALID_METHOD) {
|
||||
|
||||
if (base->is_ref()) {
|
||||
err_text="Attempted to free a reference.";
|
||||
break;
|
||||
} else if (base->get_type()==Variant::OBJECT) {
|
||||
|
||||
err_text="Attempted to free a locked object (calling or emitting).";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
err_text=_get_call_error(err,"function '"+methodstr+"' in base '"+basestr+"'",(const Variant**)argptrs);
|
||||
break;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="landscape"
|
||||
android:configChanges="orientation|keyboardHidden">
|
||||
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
|
|
@ -15,8 +15,3 @@
|
|||
# 'key.alias' for the name of the key to use.
|
||||
# The password will be asked during the build when you use the 'release' target.
|
||||
|
||||
key.store=/home/luis/Downloads/carnavalguachin.keystore
|
||||
key.alias=momoselacome
|
||||
|
||||
key.store.password=12345678
|
||||
key.alias.password=12345678
|
||||
|
|
|
@ -135,7 +135,7 @@ public class Godot extends Activity implements SensorEventListener
|
|||
};
|
||||
public ResultCallback result_callback;
|
||||
|
||||
private PaymentsManager mPaymentsManager;
|
||||
private PaymentsManager mPaymentsManager = null;
|
||||
|
||||
@Override protected void onActivityResult (int requestCode, int resultCode, Intent data) {
|
||||
if(requestCode == PaymentsManager.REQUEST_CODE_FOR_PURCHASE){
|
||||
|
@ -168,6 +168,7 @@ public class Godot extends Activity implements SensorEventListener
|
|||
|
||||
@Override protected void onCreate(Bundle icicle) {
|
||||
|
||||
System.out.printf("** GODOT ACTIVITY CREATED HERE ***\n");
|
||||
|
||||
super.onCreate(icicle);
|
||||
_self = this;
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package com.android.godot;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
|
||||
public class GodotPaymentV3 extends Godot.SingletonBase {
|
||||
|
||||
private Godot activity;
|
||||
|
||||
private Integer purchaseCallbackId = 0;
|
||||
|
||||
private String accessToken;
|
||||
|
||||
private String purchaseValidationUrlPrefix;
|
||||
|
||||
public void purchase( String _sku) {
|
||||
final String sku = _sku;
|
||||
activity.getPaymentsManager().setBaseSingleton(this);
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
activity.getPaymentsManager().requestPurchase(sku);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
static public Godot.SingletonBase initialize(Activity p_activity) {
|
||||
|
||||
return new GodotPaymentV3(p_activity);
|
||||
}
|
||||
|
||||
|
||||
public GodotPaymentV3(Activity p_activity) {
|
||||
|
||||
registerClass("GodotPayments", new String[] {"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix"});
|
||||
activity=(Godot) p_activity;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void callbackSuccess(){
|
||||
GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{});
|
||||
}
|
||||
|
||||
public void callbackFail(){
|
||||
GodotLib.callobject(purchaseCallbackId, "purchase_fail", new Object[]{});
|
||||
}
|
||||
|
||||
public void callbackCancel(){
|
||||
GodotLib.callobject(purchaseCallbackId, "purchase_cancel", new Object[]{});
|
||||
}
|
||||
|
||||
public int getPurchaseCallbackId() {
|
||||
return purchaseCallbackId;
|
||||
}
|
||||
|
||||
public void setPurchaseCallbackId(int purchaseCallbackId) {
|
||||
this.purchaseCallbackId = purchaseCallbackId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getPurchaseValidationUrlPrefix(){
|
||||
return this.purchaseValidationUrlPrefix ;
|
||||
}
|
||||
|
||||
public void setPurchaseValidationUrlPrefix(String url){
|
||||
this.purchaseValidationUrlPrefix = url;
|
||||
}
|
||||
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package com.android.godot.payments;
|
||||
|
||||
import com.android.vending.billing.IInAppBillingService;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
abstract public class ConsumeTask {
|
||||
|
||||
private Context context;
|
||||
|
||||
private IInAppBillingService mService;
|
||||
public ConsumeTask(IInAppBillingService mService, Context context ){
|
||||
this.context = context;
|
||||
this.mService = mService;
|
||||
}
|
||||
|
||||
|
||||
public void consume(final String sku){
|
||||
// Log.d("XXX", "Consuming product " + sku);
|
||||
PaymentsCache pc = new PaymentsCache(context);
|
||||
Boolean isBlocked = pc.getConsumableFlag("block", sku);
|
||||
String _token = pc.getConsumableValue("token", sku);
|
||||
// Log.d("XXX", "token " + _token);
|
||||
if(!isBlocked && _token == null){
|
||||
// _token = "inapp:"+context.getPackageName()+":android.test.purchased";
|
||||
// Log.d("XXX", "Consuming product " + sku + " with token " + _token);
|
||||
}else if(!isBlocked){
|
||||
// Log.d("XXX", "It is not blocked ¿?");
|
||||
return;
|
||||
}else if(_token == null){
|
||||
// Log.d("XXX", "No token available");
|
||||
this.error("No token for sku:" + sku);
|
||||
return;
|
||||
}
|
||||
final String token = _token;
|
||||
new AsyncTask<String, String, String>(){
|
||||
|
||||
@Override
|
||||
protected String doInBackground(String... params) {
|
||||
try {
|
||||
// Log.d("XXX", "Requesting to release item.");
|
||||
int response = mService.consumePurchase(3, context.getPackageName(), token);
|
||||
// Log.d("XXX", "release response code: " + response);
|
||||
if(response == 0 || response == 8){
|
||||
return null;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
return e.getMessage();
|
||||
|
||||
}
|
||||
return "Some error";
|
||||
}
|
||||
|
||||
protected void onPostExecute(String param){
|
||||
if(param == null){
|
||||
success();
|
||||
}else{
|
||||
error(param);
|
||||
}
|
||||
}
|
||||
|
||||
}.execute();
|
||||
}
|
||||
|
||||
abstract protected void success();
|
||||
abstract protected void error(String message);
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package com.android.godot.payments;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.android.godot.GodotLib;
|
||||
import com.android.godot.utils.Crypt;
|
||||
import com.android.vending.billing.IInAppBillingService;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentSender.SendIntentException;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
abstract public class HandlePurchaseTask {
|
||||
|
||||
private Activity context;
|
||||
|
||||
public HandlePurchaseTask(Activity context ){
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
public void handlePurchaseRequest(int resultCode, Intent data){
|
||||
// Log.d("XXX", "Handling purchase response");
|
||||
// int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
|
||||
PaymentsCache pc = new PaymentsCache(context);
|
||||
|
||||
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
|
||||
// String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
|
||||
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
|
||||
try {
|
||||
Log.d("SARLANGA", purchaseData);
|
||||
|
||||
|
||||
JSONObject jo = new JSONObject(purchaseData);
|
||||
// String sku = jo.getString("productId");
|
||||
// alert("You have bought the " + sku + ". Excellent choice, aventurer!");
|
||||
// String orderId = jo.getString("orderId");
|
||||
// String packageName = jo.getString("packageName");
|
||||
String productId = jo.getString("productId");
|
||||
// Long purchaseTime = jo.getLong("purchaseTime");
|
||||
// Integer state = jo.getInt("purchaseState");
|
||||
String developerPayload = jo.getString("developerPayload");
|
||||
String purchaseToken = jo.getString("purchaseToken");
|
||||
|
||||
if(! pc.getConsumableValue("validation_hash", productId).equals(developerPayload) ) {
|
||||
error("Untrusted callback");
|
||||
return;
|
||||
}
|
||||
|
||||
pc.setConsumableValue("ticket", productId, purchaseData);
|
||||
pc.setConsumableFlag("block", productId, true);
|
||||
pc.setConsumableValue("token", productId, purchaseToken);
|
||||
|
||||
success(purchaseToken, productId);
|
||||
return;
|
||||
} catch (JSONException e) {
|
||||
error(e.getMessage());
|
||||
}
|
||||
}else if( resultCode == Activity.RESULT_CANCELED){
|
||||
canceled();
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected void success(String purchaseToken, String sku);
|
||||
abstract protected void error(String message);
|
||||
abstract protected void canceled();
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.android.godot.payments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
public class PaymentsCache {
|
||||
|
||||
public Context context;
|
||||
|
||||
public PaymentsCache(Context context){
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
public void setConsumableFlag(String set, String sku, Boolean flag){
|
||||
SharedPreferences sharedPref = context.getSharedPreferences("consumables_" + set, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putBoolean(sku, flag);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public boolean getConsumableFlag(String set, String sku){
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(
|
||||
"consumables_" + set, Context.MODE_PRIVATE);
|
||||
return sharedPref.getBoolean(sku, false);
|
||||
}
|
||||
|
||||
|
||||
public void setConsumableValue(String set, String sku, String value){
|
||||
SharedPreferences sharedPref = context.getSharedPreferences("consumables_" + set, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putString(sku, value);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public String getConsumableValue(String set, String sku){
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(
|
||||
"consumables_" + set, Context.MODE_PRIVATE);
|
||||
return sharedPref.getString(sku, null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
package com.android.godot.payments;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.IBinder;
|
||||
|
||||
import com.android.godot.Godot;
|
||||
import com.android.godot.GodotPaymentV3;
|
||||
import com.android.vending.billing.IInAppBillingService;
|
||||
|
||||
public class PaymentsManager {
|
||||
|
||||
public static final int BILLING_RESPONSE_RESULT_OK = 0;
|
||||
|
||||
|
||||
public static final int REQUEST_CODE_FOR_PURCHASE = 0x1001;
|
||||
|
||||
|
||||
private Activity activity;
|
||||
IInAppBillingService mService;
|
||||
|
||||
|
||||
public void setActivity(Activity activity){
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
public static PaymentsManager createManager(Activity activity){
|
||||
PaymentsManager manager = new PaymentsManager(activity);
|
||||
return manager;
|
||||
}
|
||||
|
||||
private PaymentsManager(Activity activity){
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
public PaymentsManager initService(){
|
||||
activity.bindService(
|
||||
new Intent("com.android.vending.billing.InAppBillingService.BIND"),
|
||||
mServiceConn,
|
||||
Context.BIND_AUTO_CREATE);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void destroy(){
|
||||
if (mService != null) {
|
||||
activity.unbindService(mServiceConn);
|
||||
}
|
||||
}
|
||||
|
||||
ServiceConnection mServiceConn = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
mService = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name,
|
||||
IBinder service) {
|
||||
mService = IInAppBillingService.Stub.asInterface(service);
|
||||
}
|
||||
};
|
||||
|
||||
public void requestPurchase(String sku){
|
||||
new PurchaseTask(mService, Godot.getInstance()) {
|
||||
|
||||
@Override
|
||||
protected void error(String message) {
|
||||
godotPaymentV3.callbackFail();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void canceled() {
|
||||
godotPaymentV3.callbackCancel();
|
||||
}
|
||||
}.purchase(sku);
|
||||
|
||||
}
|
||||
|
||||
public void processPurchaseResponse(int resultCode, Intent data) {
|
||||
new HandlePurchaseTask(activity){
|
||||
|
||||
@Override
|
||||
protected void success(String purchaseToken, String sku) {
|
||||
validatePurchase(purchaseToken, sku);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void error(String message) {
|
||||
godotPaymentV3.callbackFail();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void canceled() {
|
||||
godotPaymentV3.callbackCancel();
|
||||
|
||||
}}.handlePurchaseRequest(resultCode, data);
|
||||
}
|
||||
|
||||
public void validatePurchase(String purchaseToken, final String sku){
|
||||
|
||||
new ValidateTask(activity, godotPaymentV3){
|
||||
|
||||
@Override
|
||||
protected void success() {
|
||||
|
||||
new ConsumeTask(mService, activity) {
|
||||
|
||||
@Override
|
||||
protected void success() {
|
||||
godotPaymentV3.callbackSuccess();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void error(String message) {
|
||||
godotPaymentV3.callbackFail();
|
||||
|
||||
}
|
||||
}.consume(sku);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void error(String message) {
|
||||
godotPaymentV3.callbackFail();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void canceled() {
|
||||
godotPaymentV3.callbackCancel();
|
||||
|
||||
}
|
||||
}.validatePurchase(sku);
|
||||
}
|
||||
|
||||
private GodotPaymentV3 godotPaymentV3;
|
||||
|
||||
public void setBaseSingleton(GodotPaymentV3 godotPaymentV3) {
|
||||
this.godotPaymentV3 = godotPaymentV3;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
package com.android.godot.payments;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.android.godot.GodotLib;
|
||||
import com.android.godot.utils.Crypt;
|
||||
import com.android.vending.billing.IInAppBillingService;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentSender.SendIntentException;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
abstract public class PurchaseTask {
|
||||
|
||||
private Activity context;
|
||||
|
||||
private IInAppBillingService mService;
|
||||
public PurchaseTask(IInAppBillingService mService, Activity context ){
|
||||
this.context = context;
|
||||
this.mService = mService;
|
||||
}
|
||||
|
||||
|
||||
private boolean isLooping = false;
|
||||
|
||||
public void purchase(final String sku){
|
||||
// Log.d("XXX", "Starting purchase");
|
||||
PaymentsCache pc = new PaymentsCache(context);
|
||||
Boolean isBlocked = pc.getConsumableFlag("block", sku);
|
||||
// if(isBlocked){
|
||||
// Log.d("XXX", "Is awaiting payment confirmation");
|
||||
// error("Awaiting payment confirmation");
|
||||
// return;
|
||||
// }
|
||||
final String hash = Crypt.createRandomHash() + Crypt.createRandomHash();
|
||||
|
||||
Bundle buyIntentBundle;
|
||||
try {
|
||||
buyIntentBundle = mService.getBuyIntent(3, context.getApplicationContext().getPackageName(), sku, "inapp", hash );
|
||||
} catch (RemoteException e) {
|
||||
// Log.d("XXX", "Error: " + e.getMessage());
|
||||
error(e.getMessage());
|
||||
return;
|
||||
}
|
||||
Object rc = buyIntentBundle.get("RESPONSE_CODE");
|
||||
int responseCode = 0;
|
||||
if(rc == null){
|
||||
responseCode = PaymentsManager.BILLING_RESPONSE_RESULT_OK;
|
||||
}else if( rc instanceof Integer){
|
||||
responseCode = ((Integer)rc).intValue();
|
||||
}else if( rc instanceof Long){
|
||||
responseCode = (int)((Long)rc).longValue();
|
||||
}
|
||||
// Log.d("XXX", "Buy intent response code: " + responseCode);
|
||||
if(responseCode == 1 || responseCode == 3 || responseCode == 4){
|
||||
canceled();
|
||||
return ;
|
||||
}
|
||||
if(responseCode == 7){
|
||||
new ConsumeTask(mService, context) {
|
||||
|
||||
@Override
|
||||
protected void success() {
|
||||
// Log.d("XXX", "Product was erroniously purchased!");
|
||||
if(isLooping){
|
||||
// Log.d("XXX", "It is looping");
|
||||
error("Error while purchasing product");
|
||||
return;
|
||||
}
|
||||
isLooping=true;
|
||||
PurchaseTask.this.purchase(sku);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void error(String message) {
|
||||
PurchaseTask.this.error(message);
|
||||
|
||||
}
|
||||
}.consume(sku);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
|
||||
pc.setConsumableValue("validation_hash", sku, hash);
|
||||
try {
|
||||
if(context == null){
|
||||
// Log.d("XXX", "No context!");
|
||||
}
|
||||
if(pendingIntent == null){
|
||||
// Log.d("XXX", "No pending intent");
|
||||
}
|
||||
// Log.d("XXX", "Starting activity for purchase!");
|
||||
context.startIntentSenderForResult(
|
||||
pendingIntent.getIntentSender(),
|
||||
PaymentsManager.REQUEST_CODE_FOR_PURCHASE,
|
||||
new Intent(),
|
||||
Integer.valueOf(0), Integer.valueOf(0),
|
||||
Integer.valueOf(0));
|
||||
} catch (SendIntentException e) {
|
||||
error(e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
abstract protected void error(String message);
|
||||
abstract protected void canceled();
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package com.android.godot.payments;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.android.godot.Godot;
|
||||
import com.android.godot.GodotLib;
|
||||
import com.android.godot.GodotPaymentV3;
|
||||
import com.android.godot.utils.Crypt;
|
||||
import com.android.godot.utils.HttpRequester;
|
||||
import com.android.godot.utils.RequestParams;
|
||||
import com.android.vending.billing.IInAppBillingService;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentSender.SendIntentException;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
abstract public class ValidateTask {
|
||||
|
||||
private Activity context;
|
||||
private GodotPaymentV3 godotPaymentsV3;
|
||||
public ValidateTask(Activity context, GodotPaymentV3 godotPaymentsV3){
|
||||
this.context = context;
|
||||
this.godotPaymentsV3 = godotPaymentsV3;
|
||||
}
|
||||
|
||||
public void validatePurchase(final String sku){
|
||||
new AsyncTask<String, String, String>(){
|
||||
|
||||
|
||||
private ProgressDialog dialog;
|
||||
|
||||
@Override
|
||||
protected void onPreExecute(){
|
||||
dialog = ProgressDialog.show(context, null, "Please wait...");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(String... params) {
|
||||
PaymentsCache pc = new PaymentsCache(context);
|
||||
String url = godotPaymentsV3.getPurchaseValidationUrlPrefix();
|
||||
RequestParams param = new RequestParams();
|
||||
param.setUrl(url);
|
||||
param.put("ticket", pc.getConsumableValue("ticket", sku));
|
||||
param.put("purchaseToken", pc.getConsumableValue("token", sku));
|
||||
param.put("sku", sku);
|
||||
// Log.d("XXX", "Haciendo request a " + url);
|
||||
// Log.d("XXX", "ticket: " + pc.getConsumableValue("ticket", sku));
|
||||
// Log.d("XXX", "purchaseToken: " + pc.getConsumableValue("token", sku));
|
||||
// Log.d("XXX", "sku: " + sku);
|
||||
param.put("package", context.getApplicationContext().getPackageName());
|
||||
HttpRequester requester = new HttpRequester();
|
||||
String jsonResponse = requester.post(param);
|
||||
// Log.d("XXX", "Validation response:\n"+jsonResponse);
|
||||
return jsonResponse;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String response){
|
||||
if(dialog != null){
|
||||
dialog.dismiss();
|
||||
}
|
||||
JSONObject j;
|
||||
try {
|
||||
j = new JSONObject(response);
|
||||
if(j.getString("status").equals("OK")){
|
||||
success();
|
||||
return;
|
||||
}else if(j.getString("status") != null){
|
||||
error(j.getString("message"));
|
||||
}else{
|
||||
error("Connection error");
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
error(e.getMessage());
|
||||
}catch (Exception e){
|
||||
error(e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}.execute();
|
||||
}
|
||||
abstract protected void success();
|
||||
abstract protected void error(String message);
|
||||
abstract protected void canceled();
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.android.godot.utils;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Random;
|
||||
|
||||
public class Crypt {
|
||||
|
||||
public static String md5(String input){
|
||||
try {
|
||||
// Create MD5 Hash
|
||||
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
|
||||
digest.update(input.getBytes());
|
||||
byte messageDigest[] = digest.digest();
|
||||
|
||||
// Create Hex String
|
||||
StringBuffer hexString = new StringBuffer();
|
||||
for (int i=0; i<messageDigest.length; i++)
|
||||
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
|
||||
return hexString.toString();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String createRandomHash(){
|
||||
return md5(Long.toString(createRandomLong()));
|
||||
}
|
||||
|
||||
public static long createAbsRandomLong(){
|
||||
return Math.abs(createRandomLong());
|
||||
}
|
||||
|
||||
public static long createRandomLong(){
|
||||
Random r = new Random();
|
||||
return r.nextLong();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.android.godot.utils;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Luis Linietsky <luis.linietsky@gmail.com>
|
||||
*/
|
||||
public class CustomSSLSocketFactory extends SSLSocketFactory {
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
|
||||
public CustomSSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
|
||||
super(truststore);
|
||||
|
||||
TrustManager tm = new X509TrustManager() {
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||
}
|
||||
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||
}
|
||||
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
sslContext.init(null, new TrustManager[] { tm }, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
|
||||
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket() throws IOException {
|
||||
return sslContext.getSocketFactory().createSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
package com.android.godot.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.KeyStore;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.conn.ClientConnectionManager;
|
||||
import org.apache.http.conn.scheme.PlainSocketFactory;
|
||||
import org.apache.http.conn.scheme.Scheme;
|
||||
import org.apache.http.conn.scheme.SchemeRegistry;
|
||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.params.BasicHttpParams;
|
||||
import org.apache.http.params.HttpConnectionParams;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.apache.http.params.HttpProtocolParams;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Luis Linietsky <luis.linietsky@gmail.com>
|
||||
*/
|
||||
public class HttpRequester {
|
||||
|
||||
private Context context;
|
||||
private static final int TTL = 600000; // 10 minutos
|
||||
private long cttl=0;
|
||||
|
||||
public HttpRequester(){
|
||||
// Log.d("XXX", "Creando http request sin contexto");
|
||||
}
|
||||
|
||||
public HttpRequester(Context context){
|
||||
this.context=context;
|
||||
// Log.d("XXX", "Creando http request con contexto");
|
||||
}
|
||||
|
||||
public String post(RequestParams params){
|
||||
HttpPost httppost = new HttpPost(params.getUrl());
|
||||
try {
|
||||
httppost.setEntity(new UrlEncodedFormEntity(params.toPairsList()));
|
||||
return request(httppost);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String get(RequestParams params){
|
||||
String response = getResponseFromCache(params.getUrl());
|
||||
if(response == null){
|
||||
// Log.d("XXX", "Cache miss!");
|
||||
HttpGet httpget = new HttpGet(params.getUrl());
|
||||
long timeInit = new Date().getTime();
|
||||
response = request(httpget);
|
||||
long delay = new Date().getTime() - timeInit;
|
||||
Log.d("com.app11tt.android.utils.HttpRequest::get(url)", "Url: " + params.getUrl() + " downloaded in " + String.format("%.03f", delay/1000.0f) + " seconds");
|
||||
if(response == null || response.length() == 0){
|
||||
response = "";
|
||||
}else{
|
||||
saveResponseIntoCache(params.getUrl(), response);
|
||||
}
|
||||
}
|
||||
Log.d("XXX", "Req: " + params.getUrl());
|
||||
Log.d("XXX", "Resp: " + response);
|
||||
return response;
|
||||
}
|
||||
|
||||
private String request(HttpUriRequest request){
|
||||
// Log.d("XXX", "Haciendo request a: " + request.getURI() );
|
||||
Log.d("PPP", "Haciendo request a: " + request.getURI() );
|
||||
long init = new Date().getTime();
|
||||
HttpClient httpclient = getNewHttpClient();
|
||||
HttpParams httpParameters = httpclient.getParams();
|
||||
HttpConnectionParams.setConnectionTimeout(httpParameters, 0);
|
||||
HttpConnectionParams.setSoTimeout(httpParameters, 0);
|
||||
HttpConnectionParams.setTcpNoDelay(httpParameters, true);
|
||||
try {
|
||||
HttpResponse response = httpclient.execute(request);
|
||||
Log.d("PPP", "Fin de request (" + (new Date().getTime() - init) + ") a: " + request.getURI() );
|
||||
// Log.d("XXX1", "Status:" + response.getStatusLine().toString());
|
||||
if(response.getStatusLine().getStatusCode() == 200){
|
||||
String strResponse = EntityUtils.toString(response.getEntity());
|
||||
// Log.d("XXX2", strResponse);
|
||||
return strResponse;
|
||||
}else{
|
||||
Log.d("XXX3", "Response status code:" + response.getStatusLine().getStatusCode() + "\n" + EntityUtils.toString(response.getEntity()));
|
||||
return null;
|
||||
}
|
||||
|
||||
} catch (ClientProtocolException e) {
|
||||
Log.d("XXX3", e.getMessage());
|
||||
} catch (IOException e) {
|
||||
Log.d("XXX4", e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private HttpClient getNewHttpClient() {
|
||||
try {
|
||||
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
trustStore.load(null, null);
|
||||
|
||||
SSLSocketFactory sf = new CustomSSLSocketFactory(trustStore);
|
||||
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||
|
||||
HttpParams params = new BasicHttpParams();
|
||||
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
|
||||
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
|
||||
|
||||
SchemeRegistry registry = new SchemeRegistry();
|
||||
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
|
||||
registry.register(new Scheme("https", sf, 443));
|
||||
|
||||
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
|
||||
|
||||
return new DefaultHttpClient(ccm, params);
|
||||
} catch (Exception e) {
|
||||
return new DefaultHttpClient();
|
||||
}
|
||||
}
|
||||
|
||||
private static String convertStreamToString(InputStream is) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line = null;
|
||||
try {
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append((line + "\n"));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void saveResponseIntoCache(String request, String response){
|
||||
if(context == null){
|
||||
// Log.d("XXX", "No context, cache failed!");
|
||||
return;
|
||||
}
|
||||
SharedPreferences sharedPref = context.getSharedPreferences("http_get_cache", Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putString("request_" + Crypt.md5(request), response);
|
||||
editor.putLong("request_" + Crypt.md5(request) + "_ttl", new Date().getTime() + getTtl());
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
|
||||
public String getResponseFromCache(String request){
|
||||
if(context == null){
|
||||
Log.d("XXX", "No context, cache miss");
|
||||
return null;
|
||||
}
|
||||
SharedPreferences sharedPref = context.getSharedPreferences( "http_get_cache", Context.MODE_PRIVATE);
|
||||
long ttl = getResponseTtl(request);
|
||||
if(ttl == 0l || (new Date().getTime() - ttl) > 0l){
|
||||
Log.d("XXX", "Cache invalid ttl:" + ttl + " vs now:" + new Date().getTime());
|
||||
return null;
|
||||
}
|
||||
return sharedPref.getString("request_" + Crypt.md5(request), null);
|
||||
}
|
||||
|
||||
public long getResponseTtl(String request){
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(
|
||||
"http_get_cache", Context.MODE_PRIVATE);
|
||||
return sharedPref.getLong("request_" + Crypt.md5(request) + "_ttl", 0l);
|
||||
}
|
||||
|
||||
public long getTtl() {
|
||||
return cttl > 0 ? cttl : TTL;
|
||||
}
|
||||
|
||||
public void setTtl(long ttl) {
|
||||
this.cttl = (ttl*1000) + new Date().getTime();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package com.android.godot.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Luis Linietsky <luis.linietsky@gmail.com>
|
||||
*/
|
||||
public class RequestParams {
|
||||
|
||||
private HashMap<String,String> params;
|
||||
private String url;
|
||||
|
||||
public RequestParams(){
|
||||
params = new HashMap<String,String>();
|
||||
}
|
||||
|
||||
public void put(String key, String value){
|
||||
params.put(key, value);
|
||||
}
|
||||
|
||||
public String get(String key){
|
||||
return params.get(key);
|
||||
}
|
||||
|
||||
public void remove(Object key){
|
||||
params.remove(key);
|
||||
}
|
||||
|
||||
public boolean has(String key){
|
||||
return params.containsKey(key);
|
||||
}
|
||||
|
||||
public List<NameValuePair> toPairsList(){
|
||||
List<NameValuePair> fields = new ArrayList<NameValuePair>();
|
||||
|
||||
for(String key : params.keySet()){
|
||||
fields.add(new BasicNameValuePair(key, this.get(key)));
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.vending.billing;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* InAppBillingService is the service that provides in-app billing version 3 and beyond.
|
||||
* This service provides the following features:
|
||||
* 1. Provides a new API to get details of in-app items published for the app including
|
||||
* price, type, title and description.
|
||||
* 2. The purchase flow is synchronous and purchase information is available immediately
|
||||
* after it completes.
|
||||
* 3. Purchase information of in-app purchases is maintained within the Google Play system
|
||||
* till the purchase is consumed.
|
||||
* 4. An API to consume a purchase of an inapp item. All purchases of one-time
|
||||
* in-app items are consumable and thereafter can be purchased again.
|
||||
* 5. An API to get current purchases of the user immediately. This will not contain any
|
||||
* consumed purchases.
|
||||
*
|
||||
* All calls will give a response code with the following possible values
|
||||
* RESULT_OK = 0 - success
|
||||
* RESULT_USER_CANCELED = 1 - user pressed back or canceled a dialog
|
||||
* RESULT_BILLING_UNAVAILABLE = 3 - this billing API version is not supported for the type requested
|
||||
* RESULT_ITEM_UNAVAILABLE = 4 - requested SKU is not available for purchase
|
||||
* RESULT_DEVELOPER_ERROR = 5 - invalid arguments provided to the API
|
||||
* RESULT_ERROR = 6 - Fatal error during the API action
|
||||
* RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned
|
||||
* RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned
|
||||
*/
|
||||
interface IInAppBillingService {
|
||||
/**
|
||||
* Checks support for the requested billing API version, package and in-app type.
|
||||
* Minimum API version supported by this interface is 3.
|
||||
* @param apiVersion the billing version which the app is using
|
||||
* @param packageName the package name of the calling app
|
||||
* @param type type of the in-app item being purchased "inapp" for one-time purchases
|
||||
* and "subs" for subscription.
|
||||
* @return RESULT_OK(0) on success, corresponding result code on failures
|
||||
*/
|
||||
int isBillingSupported(int apiVersion, String packageName, String type);
|
||||
|
||||
/**
|
||||
* Provides details of a list of SKUs
|
||||
* Given a list of SKUs of a valid type in the skusBundle, this returns a bundle
|
||||
* with a list JSON strings containing the productId, price, title and description.
|
||||
* This API can be called with a maximum of 20 SKUs.
|
||||
* @param apiVersion billing API version that the Third-party is using
|
||||
* @param packageName the package name of the calling app
|
||||
* @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST"
|
||||
* @return Bundle containing the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
|
||||
* failure as listed above.
|
||||
* "DETAILS_LIST" with a StringArrayList containing purchase information
|
||||
* in JSON format similar to:
|
||||
* '{ "productId" : "exampleSku", "type" : "inapp", "price" : "$5.00",
|
||||
* "title : "Example Title", "description" : "This is an example description" }'
|
||||
*/
|
||||
Bundle getSkuDetails(int apiVersion, String packageName, String type, in Bundle skusBundle);
|
||||
|
||||
/**
|
||||
* Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU,
|
||||
* the type, a unique purchase token and an optional developer payload.
|
||||
* @param apiVersion billing API version that the app is using
|
||||
* @param packageName package name of the calling app
|
||||
* @param sku the SKU of the in-app item as published in the developer console
|
||||
* @param type the type of the in-app item ("inapp" for one-time purchases
|
||||
* and "subs" for subscription).
|
||||
* @param developerPayload optional argument to be sent back with the purchase information
|
||||
* @return Bundle containing the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
|
||||
* failure as listed above.
|
||||
* "BUY_INTENT" - PendingIntent to start the purchase flow
|
||||
*
|
||||
* The Pending intent should be launched with startIntentSenderForResult. When purchase flow
|
||||
* has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
|
||||
* If the purchase is successful, the result data will contain the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
|
||||
* failure as listed above.
|
||||
* "INAPP_PURCHASE_DATA" - String in JSON format similar to
|
||||
* '{"orderId":"12999763169054705758.1371079406387615",
|
||||
* "packageName":"com.example.app",
|
||||
* "productId":"exampleSku",
|
||||
* "purchaseTime":1345678900000,
|
||||
* "purchaseToken" : "122333444455555",
|
||||
* "developerPayload":"example developer payload" }'
|
||||
* "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
|
||||
* was signed with the private key of the developer
|
||||
* TODO: change this to app-specific keys.
|
||||
*/
|
||||
Bundle getBuyIntent(int apiVersion, String packageName, String sku, String type,
|
||||
String developerPayload);
|
||||
|
||||
/**
|
||||
* Returns the current SKUs owned by the user of the type and package name specified along with
|
||||
* purchase information and a signature of the data to be validated.
|
||||
* This will return all SKUs that have been purchased in V3 and managed items purchased using
|
||||
* V1 and V2 that have not been consumed.
|
||||
* @param apiVersion billing API version that the app is using
|
||||
* @param packageName package name of the calling app
|
||||
* @param type the type of the in-app items being requested
|
||||
* ("inapp" for one-time purchases and "subs" for subscription).
|
||||
* @param continuationToken to be set as null for the first call, if the number of owned
|
||||
* skus are too many, a continuationToken is returned in the response bundle.
|
||||
* This method can be called again with the continuation token to get the next set of
|
||||
* owned skus.
|
||||
* @return Bundle containing the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
|
||||
* failure as listed above.
|
||||
* "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs
|
||||
* "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information
|
||||
* "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures
|
||||
* of the purchase information
|
||||
* "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
|
||||
* next set of in-app purchases. Only set if the
|
||||
* user has more owned skus than the current list.
|
||||
*/
|
||||
Bundle getPurchases(int apiVersion, String packageName, String type, String continuationToken);
|
||||
|
||||
/**
|
||||
* Consume the last purchase of the given SKU. This will result in this item being removed
|
||||
* from all subsequent responses to getPurchases() and allow re-purchase of this item.
|
||||
* @param apiVersion billing API version that the app is using
|
||||
* @param packageName package name of the calling app
|
||||
* @param purchaseToken token in the purchase information JSON that identifies the purchase
|
||||
* to be consumed
|
||||
* @return 0 if consumption succeeded. Appropriate error values for failures.
|
||||
*/
|
||||
int consumePurchase(int apiVersion, String packageName, String purchaseToken);
|
||||
}
|
|
@ -440,7 +440,8 @@ public:
|
|||
case Variant::STRING: {
|
||||
|
||||
jobject o = env->CallObjectMethodA(instance,E->get().method,v);
|
||||
String singname = env->GetStringUTFChars((jstring)o, NULL );
|
||||
String str = env->GetStringUTFChars((jstring)o, NULL );
|
||||
ret=str;
|
||||
} break;
|
||||
case Variant::STRING_ARRAY: {
|
||||
|
||||
|
@ -665,11 +666,12 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env,
|
|||
|
||||
|
||||
initialized=true;
|
||||
_godot_instance=activity;
|
||||
|
||||
JavaVM *jvm;
|
||||
env->GetJavaVM(&jvm);
|
||||
|
||||
_godot_instance=env->NewGlobalRef(activity);
|
||||
// _godot_instance=activity;
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","***************** HELLO FROM JNI!!!!!!!!");
|
||||
|
||||
|
@ -816,8 +818,10 @@ static void _initialize_java_modules() {
|
|||
jmethodID getClassLoader = env->GetMethodID(activityClass,"getClassLoader", "()Ljava/lang/ClassLoader;");
|
||||
|
||||
jobject cls = env->CallObjectMethod(_godot_instance, getClassLoader);
|
||||
//cls=env->NewGlobalRef(cls);
|
||||
|
||||
jclass classLoader = env->FindClass("java/lang/ClassLoader");
|
||||
//classLoader=(jclass)env->NewGlobalRef(classLoader);
|
||||
|
||||
jmethodID findClass = env->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
|
||||
|
||||
|
@ -835,6 +839,7 @@ static void _initialize_java_modules() {
|
|||
ERR_EXPLAIN("Couldn't find singleton for class: "+m);
|
||||
ERR_CONTINUE(!singletonClass);
|
||||
}
|
||||
//singletonClass=(jclass)env->NewGlobalRef(singletonClass);
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","****^*^*?^*^*class data %x",singletonClass);
|
||||
jmethodID initialize = env->GetStaticMethodID(singletonClass, "initialize", "(Landroid/app/Activity;)Lcom/android/godot/Godot$SingletonBase;");
|
||||
|
|
|
@ -108,8 +108,15 @@ static int frame_count = 0;
|
|||
if ([[UIDevice currentDevice]respondsToSelector:@selector(identifierForVendor)]) {
|
||||
uuid = [UIDevice currentDevice].identifierForVendor.UUIDString;
|
||||
}else{
|
||||
// return [UIDevice currentDevice]. uniqueIdentifier
|
||||
uuid = [[UIDevice currentDevice] performSelector:@selector(uniqueIdentifier)];
|
||||
|
||||
// before iOS 6, so just generate an identifier and store it
|
||||
uuid = [[NSUserDefaults standardUserDefaults] objectForKey:@"identiferForVendor"];
|
||||
if( !uuid ) {
|
||||
CFUUIDRef cfuuid = CFUUIDCreate(NULL);
|
||||
uuid = (__bridge_transfer NSString*)CFUUIDCreateString(NULL, cfuuid);
|
||||
CFRelease(cfuuid);
|
||||
[[NSUserDefaults standardUserDefaults] setObject:uuid forKey:@"identifierForVendor"];
|
||||
}
|
||||
}
|
||||
|
||||
OSIPhone::get_singleton()->set_unique_ID(String::utf8([uuid UTF8String]));
|
||||
|
|
|
@ -37,7 +37,6 @@ def get_flags():
|
|||
('tools', 'yes'),
|
||||
('nedmalloc', 'no'),
|
||||
('webp', 'yes'),
|
||||
('module_FacebookScorer_ios_enabled', 'no'),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -64,25 +64,22 @@ bool _play_video(String p_path) {
|
|||
|
||||
p_path = Globals::get_singleton()->globalize_path(p_path);
|
||||
|
||||
// NSString *file_path = [NSString stringWithCString:p_path.utf8().get_data() encoding:NSASCIIStringEncoding];
|
||||
NSString* file_path = [[[NSString alloc] initWithUTF8String:p_path.utf8().get_data()] autorelease];
|
||||
NSURL *file_url = [NSURL fileURLWithPath:file_path];
|
||||
|
||||
_instance.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:file_url];
|
||||
_instance.moviePlayerController.controlStyle = MPMovieControlStyleNone;
|
||||
[_instance.moviePlayerController setScalingMode:MPMovieScalingModeAspectFit];
|
||||
// [_instance.moviePlayerController setScalingMode:MPMovieScalingModeAspectFill];
|
||||
// [_instance.moviePlayerController setScalingMode:MPMovieScalingModeAspectFit];
|
||||
[_instance.moviePlayerController setScalingMode:MPMovieScalingModeAspectFill];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:_instance
|
||||
selector:@selector(moviePlayBackDidFinish:)
|
||||
name:MPMoviePlayerPlaybackDidFinishNotification
|
||||
object:_instance.moviePlayerController];
|
||||
|
||||
[[_instance window] makeKeyAndVisible];
|
||||
_instance.backgroundWindow = [[UIApplication sharedApplication] keyWindow];
|
||||
[_instance.moviePlayerController.view setFrame:_instance.backgroundWindow.frame];
|
||||
[_instance.moviePlayerController.view setFrame:_instance.bounds];
|
||||
_instance.moviePlayerController.view.userInteractionEnabled = NO;
|
||||
[_instance.backgroundWindow addSubview:_instance.moviePlayerController.view];
|
||||
[_instance addSubview:_instance.moviePlayerController.view];
|
||||
[_instance.moviePlayerController play];
|
||||
|
||||
return true;
|
||||
|
@ -484,6 +481,14 @@ static void clear_touches() {
|
|||
return self;
|
||||
}
|
||||
|
||||
// -(BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers {
|
||||
// return YES;
|
||||
// }
|
||||
|
||||
// - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
|
||||
// return YES;
|
||||
// }
|
||||
|
||||
// Stop animating and release resources when they are no longer needed.
|
||||
- (void)dealloc
|
||||
{
|
||||
|
@ -510,8 +515,4 @@ static void clear_touches() {
|
|||
_stop_video();
|
||||
}
|
||||
|
||||
- (void)handleTap:(UITapGestureRecognizer *)gesture {
|
||||
NSLog(@"Gesture\n");
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -167,6 +167,31 @@ Error InAppStore::request_product_info(Variant p_params) {
|
|||
ret["type"] = "purchase";
|
||||
ret["result"] = "ok";
|
||||
ret["product_id"] = pid;
|
||||
|
||||
if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0){
|
||||
|
||||
NSURL *receiptFileURL = nil;
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
if ([bundle respondsToSelector:@selector(appStoreReceiptURL)]) {
|
||||
|
||||
// Get the transaction receipt file path location in the app bundle.
|
||||
receiptFileURL = [bundle appStoreReceiptURL];
|
||||
|
||||
// Read in the contents of the transaction file.
|
||||
ret["receipt"] = receiptFileURL;
|
||||
|
||||
} else {
|
||||
// Fall back to deprecated transaction receipt,
|
||||
// which is still available in iOS 7.
|
||||
|
||||
// Use SKPaymentTransaction's transactionReceipt.
|
||||
ret["receipt"] = transaction.transactionReceipt;
|
||||
}
|
||||
|
||||
}else{
|
||||
ret["receipt"] = transaction.transactionReceipt;
|
||||
}
|
||||
|
||||
InAppStore::get_singleton()->_post_event(ret);
|
||||
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
|
||||
} break;
|
||||
|
|
|
@ -38,7 +38,6 @@ def get_flags():
|
|||
('tools', 'yes'),
|
||||
('nedmalloc', 'no'),
|
||||
('webp', 'yes'),
|
||||
('module_FacebookScorer_ios_enabled', 'no'),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -715,17 +715,18 @@ bool CanvasItem::is_block_transform_notify_enabled() const {
|
|||
return block_transform_notify;
|
||||
}
|
||||
|
||||
void CanvasItem::set_on_top(bool p_on_top) {
|
||||
void CanvasItem::set_draw_behind_parent(bool p_enable) {
|
||||
|
||||
if (on_top==p_on_top)
|
||||
if (behind==p_enable)
|
||||
return;
|
||||
on_top=p_on_top;
|
||||
VisualServer::get_singleton()->canvas_item_set_on_top(canvas_item,on_top);
|
||||
behind=p_enable;
|
||||
VisualServer::get_singleton()->canvas_item_set_on_top(canvas_item,!behind);
|
||||
|
||||
}
|
||||
|
||||
bool CanvasItem::is_on_top() const {
|
||||
bool CanvasItem::is_draw_behind_parent_enabled() const{
|
||||
|
||||
return on_top;
|
||||
return behind;
|
||||
}
|
||||
|
||||
|
||||
|
@ -764,8 +765,11 @@ void CanvasItem::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("set_self_opacity","self_opacity"),&CanvasItem::set_self_opacity);
|
||||
ObjectTypeDB::bind_method(_MD("get_self_opacity"),&CanvasItem::get_self_opacity);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_on_top","on_top"),&CanvasItem::set_on_top);
|
||||
ObjectTypeDB::bind_method(_MD("is_on_top"),&CanvasItem::is_on_top);
|
||||
ObjectTypeDB::bind_method(_MD("set_draw_behind_parent","enabe"),&CanvasItem::set_draw_behind_parent);
|
||||
ObjectTypeDB::bind_method(_MD("is_draw_behind_parent_enabled"),&CanvasItem::is_draw_behind_parent_enabled);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_set_on_top","on_top"),&CanvasItem::_set_on_top);
|
||||
ObjectTypeDB::bind_method(_MD("_is_on_top"),&CanvasItem::_is_on_top);
|
||||
|
||||
//ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform);
|
||||
|
||||
|
@ -796,7 +800,8 @@ void CanvasItem::_bind_methods() {
|
|||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/visible"), _SCS("_set_visible_"),_SCS("_is_visible_") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"visibility/opacity",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_opacity"),_SCS("get_opacity") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"visibility/self_opacity",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_self_opacity"),_SCS("get_self_opacity") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/on_top"), _SCS("set_on_top"),_SCS("is_on_top") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/behind_parent"), _SCS("set_draw_behind_parent"),_SCS("is_draw_behind_parent_enabled") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/on_top",PROPERTY_HINT_NONE,"",0), _SCS("_set_on_top"),_SCS("_is_on_top") ); //compatibility
|
||||
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), _SCS("set_blend_mode"),_SCS("get_blend_mode") );
|
||||
//exporting these two things doesn't really make much sense i think
|
||||
|
@ -859,7 +864,7 @@ CanvasItem::CanvasItem() : xform_change(this) {
|
|||
first_draw=false;
|
||||
blend_mode=BLEND_MODE_MIX;
|
||||
drawing=false;
|
||||
on_top=true;
|
||||
behind=false;
|
||||
block_transform_notify=false;
|
||||
viewport=NULL;
|
||||
canvas_layer=NULL;
|
||||
|
|
|
@ -77,7 +77,7 @@ private:
|
|||
bool pending_children_sort;
|
||||
bool drawing;
|
||||
bool block_transform_notify;
|
||||
bool on_top;
|
||||
bool behind;
|
||||
|
||||
mutable Matrix32 global_transform;
|
||||
mutable bool global_invalid;
|
||||
|
@ -102,6 +102,9 @@ private:
|
|||
|
||||
void _notify_transform(CanvasItem *p_node);
|
||||
|
||||
void _set_on_top(bool p_on_top) { set_draw_behind_parent(!p_on_top); }
|
||||
bool _is_on_top() const { return !is_draw_behind_parent_enabled(); }
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
@ -175,8 +178,8 @@ public:
|
|||
void set_as_toplevel(bool p_toplevel);
|
||||
bool is_set_as_toplevel() const;
|
||||
|
||||
void set_on_top(bool p_on_top);
|
||||
bool is_on_top() const;
|
||||
void set_draw_behind_parent(bool p_enable);
|
||||
bool is_draw_behind_parent_enabled() const;
|
||||
|
||||
CanvasItem *get_parent_item() const;
|
||||
|
||||
|
|
|
@ -351,11 +351,13 @@ void Control::_notification(int p_notification) {
|
|||
|
||||
window->tooltip_timer = memnew( Timer );
|
||||
add_child(window->tooltip_timer);
|
||||
window->tooltip_timer->force_parent_owned();
|
||||
window->tooltip_timer->set_wait_time( GLOBAL_DEF("display/tooltip_delay",0.7));
|
||||
window->tooltip_timer->connect("timeout",this,"_window_show_tooltip");
|
||||
window->tooltip=NULL;
|
||||
window->tooltip_popup = memnew( TooltipPanel );
|
||||
add_child(window->tooltip_popup);
|
||||
window->tooltip_popup->force_parent_owned();
|
||||
window->tooltip_label = memnew( TooltipLabel );
|
||||
window->tooltip_popup->add_child(window->tooltip_label);
|
||||
window->tooltip_popup->set_as_toplevel(true);
|
||||
|
|
|
@ -264,6 +264,8 @@ public:
|
|||
static void set_human_readable_collision_renaming(bool p_enabled);
|
||||
static void init_node_hrcr();
|
||||
|
||||
void force_parent_owned() { data.parent_owned=true; } //hack to avoid duplicate nodes
|
||||
|
||||
/* CANVAS */
|
||||
|
||||
Node();
|
||||
|
|
|
@ -375,6 +375,18 @@ bool BodyPair2DSW::setup(float p_step) {
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
c.bounce=MAX(A->get_bounce(),B->get_bounce());
|
||||
if (c.bounce) {
|
||||
|
||||
Vector2 crA( -A->get_angular_velocity() * c.rA.y, A->get_angular_velocity() * c.rA.x );
|
||||
Vector2 crB( -B->get_angular_velocity() * c.rB.y, B->get_angular_velocity() * c.rB.x );
|
||||
Vector2 dv = B->get_linear_velocity() + crB - A->get_linear_velocity() - crA;
|
||||
c.bounce = c.bounce * dv.dot(c.normal);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -420,8 +432,7 @@ void BodyPair2DSW::solve(float p_step) {
|
|||
A->apply_bias_impulse(c.rA,-jb);
|
||||
B->apply_bias_impulse(c.rB, jb);
|
||||
|
||||
real_t bounce=MAX(A->get_bounce(),B->get_bounce());
|
||||
real_t jn = -(bounce + vn)*c.mass_normal;
|
||||
real_t jn = -(c.bounce + vn)*c.mass_normal;
|
||||
real_t jnOld = c.acc_normal_impulse;
|
||||
c.acc_normal_impulse = MAX(jnOld + jn, 0.0f);
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@ class BodyPair2DSW : public Constraint2DSW {
|
|||
bool active;
|
||||
Vector2 rA,rB;
|
||||
bool reused;
|
||||
float bounce;
|
||||
|
||||
};
|
||||
|
||||
Vector2 offset_B; //use local A coordinates to avoid numerical issues on collision detection
|
||||
|
|
|
@ -510,6 +510,20 @@ void CodeTextEditor::set_error(const String& p_error) {
|
|||
|
||||
}
|
||||
|
||||
void CodeTextEditor::_update_font() {
|
||||
|
||||
String editor_font = EditorSettings::get_singleton()->get("text_editor/font");
|
||||
if (editor_font!="") {
|
||||
Ref<Font> fnt = ResourceLoader::load(editor_font);
|
||||
if (fnt.is_valid()) {
|
||||
text_editor->add_font_override("font",fnt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
text_editor->add_font_override("font",get_font("source","Fonts"));
|
||||
}
|
||||
|
||||
void CodeTextEditor::_text_changed_idle_timeout() {
|
||||
|
||||
|
||||
|
@ -527,8 +541,9 @@ void CodeTextEditor::_bind_methods() {
|
|||
|
||||
ObjectTypeDB::bind_method("_line_col_changed",&CodeTextEditor::_line_col_changed);
|
||||
ObjectTypeDB::bind_method("_text_changed",&CodeTextEditor::_text_changed);
|
||||
ObjectTypeDB::bind_method("_update_font",&CodeTextEditor::_update_font);
|
||||
ObjectTypeDB::bind_method("_text_changed_idle_timeout",&CodeTextEditor::_text_changed_idle_timeout);
|
||||
ObjectTypeDB::bind_method("_complete_request",&CodeTextEditor::_complete_request);
|
||||
ObjectTypeDB::bind_method("_complete_request",&CodeTextEditor::_complete_request);
|
||||
}
|
||||
|
||||
CodeTextEditor::CodeTextEditor() {
|
||||
|
@ -571,4 +586,5 @@ CodeTextEditor::CodeTextEditor() {
|
|||
text_editor->set_completion(true,cs);
|
||||
idle->connect("timeout", this,"_text_changed_idle_timeout");
|
||||
|
||||
EditorSettings::get_singleton()->connect("settings_changed",this,"_update_font");
|
||||
}
|
||||
|
|
|
@ -131,7 +131,9 @@ class CodeTextEditor : public Control {
|
|||
|
||||
Label *error;
|
||||
|
||||
void _complete_request(const String& p_request,int p_line);
|
||||
void _update_font();
|
||||
|
||||
void _complete_request(const String& p_request,int p_line);
|
||||
protected:
|
||||
|
||||
void set_error(const String& p_error);
|
||||
|
|
|
@ -3263,6 +3263,14 @@ EditorNode::EditorNode() {
|
|||
editor_register_icons(theme);
|
||||
editor_register_fonts(theme);
|
||||
|
||||
String global_font = EditorSettings::get_singleton()->get("global/font");
|
||||
if (global_font!="") {
|
||||
Ref<Font> fnt = ResourceLoader::load(global_font);
|
||||
if (fnt.is_valid()) {
|
||||
theme->set_default_theme_font(fnt);
|
||||
}
|
||||
}
|
||||
|
||||
Ref<StyleBoxTexture> focus_sbt=memnew( StyleBoxTexture );
|
||||
focus_sbt->set_texture(theme->get_icon("EditorFocus","EditorIcons"));
|
||||
for(int i=0;i<4;i++) {
|
||||
|
|
|
@ -384,6 +384,9 @@ void EditorSettings::_load_defaults() {
|
|||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
set("global/font","");
|
||||
hints["global/font"]=PropertyInfo(Variant::STRING,"global/font",PROPERTY_HINT_GLOBAL_FILE,"*.fnt");
|
||||
|
||||
set("text_editor/background_color",Color::html("3b000000"));
|
||||
set("text_editor/text_color",Color::html("aaaaaa"));
|
||||
set("text_editor/text_selected_color",Color::html("000000"));
|
||||
|
@ -398,6 +401,9 @@ void EditorSettings::_load_defaults() {
|
|||
set("text_editor/idle_parse_delay",2);
|
||||
set("text_editor/create_signal_callbacks",true);
|
||||
set("text_editor/autosave_interval_seconds",60);
|
||||
set("text_editor/font","");
|
||||
hints["text_editor/font"]=PropertyInfo(Variant::STRING,"text_editor/font",PROPERTY_HINT_GLOBAL_FILE,"*.fnt");
|
||||
|
||||
|
||||
set("3d_editor/default_fov",45.0);
|
||||
set("3d_editor/default_z_near",0.1);
|
||||
|
@ -429,9 +435,9 @@ void EditorSettings::_load_defaults() {
|
|||
|
||||
set("import/pvrtc_texture_tool","");
|
||||
#ifdef WINDOWS_ENABLED
|
||||
hints["import/pvrtc_texture_tool"]=PropertyInfo(Variant::STRING,"import/pvrtc_texture_tool",PROPERTY_HINT_FILE,"*.exe");
|
||||
hints["import/pvrtc_texture_tool"]=PropertyInfo(Variant::STRING,"import/pvrtc_texture_tool",PROPERTY_HINT_GLOBAL_FILE,"*.exe");
|
||||
#else
|
||||
hints["import/pvrtc_texture_tool"]=PropertyInfo(Variant::STRING,"import/pvrtc_texture_tool",PROPERTY_HINT_FILE,"");
|
||||
hints["import/pvrtc_texture_tool"]=PropertyInfo(Variant::STRING,"import/pvrtc_texture_tool",PROPERTY_HINT_GLOBAL_FILE,"");
|
||||
#endif
|
||||
set("PVRTC/fast_conversion",false);
|
||||
|
||||
|
|
|
@ -909,7 +909,14 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
|
|||
Vector<String> extensions=hint_text.split(",");
|
||||
for(int i=0;i<extensions.size();i++) {
|
||||
|
||||
file->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper() );
|
||||
String filter = extensions[i];
|
||||
if (filter.begins_with("."))
|
||||
filter="*"+extensions[i];
|
||||
else if (!filter.begins_with("*"))
|
||||
filter="*."+extensions[i];
|
||||
|
||||
|
||||
file->add_filter(filter+" ; "+extensions[i].to_upper() );
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue