-
Posts
544 -
Joined
-
Last visited
Content Type
Blogs
Forums
Store
Gallery
Videos
Posts posted by martyj
-
-
So I've wanted this feature in an engine for a really long time, it's just a very difficult task.
It would be nice if Leadwerks could have the ability to modify the map then immediately play the game without having to run a separate application. If you could "pause" your game logic in editing mode, then resume to test out new features.
I think the phrasing would be seamless integration.
Lua code would be easy to reload into the engine, whereas with C++ you would have to use calls like dlopen http://man7.org/linux/man-pages/man3/dlopen.3.html to reload compiled binaries. This may be come easier with the C++ Action Class.
I could modify my game to support this, but I would require the ability save a Map out. It would be nice to also toggle Leadwerks UI elements such as the Assets pane, or terrain editing.
At least for me, it would save a ton of time to not have to reload the game to test a feature. I spend a lot of time in my loading screen.
- 2
-
Might be easier and more reliable to store them in a queue, then use an std::thread which checks the queue for events to be sent off. That way if the game crashes, (which in C++ land happens a lot), you can still have the data.
-
Are network requests ran on a separate thread? Or will this be something that could lock up the UI?
- 1
-
I would buy an AMD APU instead of an R7 240. It would be cheaper overall. http://www.newegg.com/Product/Product.aspx?Item=9SIA1N85343534 Way better graphics performance. $50 cheaper.
DDR4 will NOT work on AMD processors. You need DDR3.
8 gigs is plenty for most users.
- 2
-
I am really excited for this functionality. I'm delaying a demo version update for this content as well.
If there's anything more I can do to help, let me know!
-
300 to 800 what? Bytes? Kilobytes? Megabytes?
It could just be the memory needed by your map. Game assets are quite large in size.
-
Success!
Did some digging around in my test code. Apparently sizeof(char*) doesn't return the size of the static array, but just the size of a charater. Thanks G++.
I can't find libcurl-dev on windows for the life of me, so I had to use Linux. As I am working off of a server, I don't have Leadwerks setup so I cannot implement it in your class.
Sorry about the indentation as well. I was using nano to modify the files.
But this should help hopefully.
- 1
-
For the life of me I cannot reproduce the hmac hash.
Using the key from the python file and the JSON from my sample, I get the following:
import hmac import hashlib key = "16813a12f718bc5c620f56944e1abc3ea13ccbac" data = "{\"platform\":\"Windows\", \"os_version\":\"10\", \"sdk_version\":\"api v2\"}"; hash = hmac.new(key, data, digestmod=hashlib.sha256) hash.hexdigest()
Produces the following HEX string a39a45d2ac53e7c4d9e3b978267a6442cad0c396a52500e6c3be9e5bb1e6edbb
Using the library I posted earlier I get a completely different result.
Using the following code which uses OpenSSL's version
#include <string.h> #include <stdio.h> #include <openssl/hmac.h> #include <openssl/evp.h> void hmac(unsigned char* key, unsigned char* message, int keylen, int messagelen, unsigned char* out) { HMAC_CTX ctx; HMAC_CTX_init(&ctx); unsigned int len = 32; unsigned char* data[32]; // Using sha1 hash engine here. // You may use other hash engines. e.g EVP_md5(), EVP_sha224, EVP_sha512, etc HMAC_Init_ex(&ctx, key, 20, EVP_sha256(), NULL); HMAC_Update(&ctx, message, messagelen); HMAC_Final(&ctx, out, &len); HMAC_CTX_cleanup(&ctx); memcpy(out, data, len); memset(out+len, 0, 32-len); for(int i = 0; i < len; i++) { printf("%02x", out[i]); } printf("\n"); } int main(int argc, const char *const *argv) { unsigned char buff[32]; const char* message = "{\"platform\":\"Windows\", \"os_version\":\"10\", \"sdk_version\":\"api v2\"}"; const char* key = "16813a12f718bc5c620f56944e1abc3ea13ccbac"; hmac((unsigned char*)key, (unsigned char*)message, sizeof(key), sizeof(message), buff); }
I get the following printed.
0000000000000000b076bf49007f0000d859c149007f00008707400000000000
This sample code seems to work well. The problem is it is only windows.
http://stackoverflow.com/questions/22147895/is-it-possible-to-do-a-hmac-with-wincrypt
- 2
-
They are combined with this hash
https://github.com/unixpickle/LibOrange/blob/master/LibOrange/hmac-sha256.c
Then base 64 encoding the result of that.
I can give you a better example Saturday morning.
-
I think their python example gives the best use case of how their auth works.
http://restapidocs.gameanalytics.com/#python-example
# sandbox game keys game_key = "5c6bcb5402204249437fb5a7a80a4959" secret_key = "16813a12f718bc5c620f56944e1abc3ea13ccbac" # sandbox API urls url_init = 'http://sandbox-api.gameanalytics.com/v2/' + game_key + '/init' init_payload = { 'platform': platform, 'os_version': os_version, 'sdk_version': sdk_version } init_payload_json = json.dumps(init_payload) headers = { 'Authorization': hmac_hash_with_secret(init_payload_json, secret_key), 'Content-Type': 'application/json' } try: init_response = requests.post(url_init, data=init_payload_json, headers=headers) except: print "Init request failed!" sys.exit()
Notice the line 'Authorization': hmac_hash_with_secret(event_list_json, secret_key),
Makes use of this function
def hmac_hash_with_secret(message, key): return base64.b64encode(hmac.new(key, message, digestmod=hashlib.sha256).digest())
Create hmac hash based upon key and message.
Base64 encode hmac hash.
-
An auto-reduction tool built into the model editor would also be ideal, in combination with the manually created objects.
- 3
-
While you're in there adding http requests with libcurl, you should make them available for other C++ developers without using libcurl .
It would be nice to do a request to a URL with a map as GET or POST params.
-
Here's a video of me testing out multiplayer syncing.
If anyone is interested in helping me test multiplayer, it would be lovely to not have to run two clients by myself!
- 2
-
Two Questions
1. Are you using the sandbox API keys for the sandbox API?
2. Are you creating the Authorization header correctly? From what I can tell, it's a hmac hash of your POST data using your secret key, then base64 encoding it
I looked into CURL a little bit further. Here is my text example thanks to libcurl's example.
/*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | * / __| | | | |_) | | * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ***************************************************************************/ /* <DESC> * simple HTTP POST using the easy interface * </DESC> */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <curl/curl.h> struct MemoryStruct { char *memory; size_t size; }; static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; struct MemoryStruct *mem = (struct MemoryStruct *)userp; mem->memory = realloc(mem->memory, mem->size + realsize + 1); if(mem->memory == NULL) { /* out of memory! */ printf("not enough memory (realloc returned NULL)\n"); return 0; } memcpy(&(mem->memory[mem->size]), contents, realsize); mem->size += realsize; mem->memory[mem->size] = 0; return realsize; } int main(void) { CURL *curl; CURLcode res; struct MemoryStruct chunk; chunk.memory = malloc(1); chunk.size = 0; char* postData = "{\"platform\":\"Windows\", \"os_version\":\"10\", \"sdk_version\":\"api v2\"}"; /* In windows, this will init the winsock stuff */ curl_global_init(CURL_GLOBAL_ALL); /* get a curl handle */ curl = curl_easy_init(); if(curl) { struct curl_slist *headers=NULL; headers = curl_slist_append(headers, "Content-Type: text/xml"); headers = curl_slist_append(headers, "Authorization: <token_from_hmac_sha256_hash_with_secret>"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); /* First set the URL that is about to receive our POST. This URL can just as well be a https:// URL if that is what should receive the data. */ curl_easy_setopt(curl, CURLOPT_URL, "http://api.gameanalytics.com/v2/<game_key_here>/init"); /* Now specify the POST data */ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(postData)); /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); /* Check for errors */ if(res != CURLE_OK) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); } else { printf("%s\n",chunk.memory); } /* always cleanup */ curl_easy_cleanup(curl); } curl_global_cleanup(); return 0; }
To generate an Hmac hash I'd check out this code: https://github.com/unixpickle/LibOrange/blob/master/LibOrange/hmac-sha256.c
Then all you have to do is to base64 encode that for your Authorization token.
- 1
-
What you're setting the body to isn't valid json.
What I would do is see if you can use CURLOPT_POSTFIELDS and pass it like this:
curl.setOptString(CURLOPT_CURLOPT_POSTFIELDS, "platform=Windows&os_version=10&sdk_version=rest api v2");
What library of CURL are you using? I can try to get a quick example tomorrow morning of each of the different requests.
-
So it looks like you have to init the API first.
POST /v2/<game_key>/init
Your body data needs the following fields: platform, os_version, sdk_version
The Docs ask for JSON to be submitted, but I'd imagine URLEncoding should work.
Once you do that, you should be able to create different events here:
POST /v2/<game_key>/events
Depending on the category in your data, your fields change.
For example, a Category of business appears to support the following fields:
category, event_id, amount, currency, transaction_num, cart_type, receipt_info
A Category even of type Resource requires the following fields:
category, event_id, amount.
-
I see.
Does having an update hook effect performance much? I have an object that I add an update hook on when it gets interacted with, then I hide the object.
After x number of seconds, I show the object, and would like to remove the hook as it's no longer needed to check to see if it should show.
What would be the best way to do this?
-
In the non-beta branch.
When removing a hook on an entity in the Hook's callback, an access violation occurs.
When removing a hook on an entity NOT in the hook, everything works as expected.
Code:
void tempHook(Entity* entity) { if (Window::GetCurrent()->KeyHit(Key::J)) { entity->RemoveHook(Entity::UpdateWorldHook, tempHook); } } bool App::Start() { temp = Model::Box(3, 3, 3); temp->AddHook(Entity::UpdateWorldHook, tempHook); return true; }
-
Are you using apache? You could use mod_rewrite.
Something like
<IfModule mod_rewrite.c> RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^workspace/(.*)$ community/$1 [R=301,L] </IfModule>
I'm not 100% sure the exact syntax as I am not an apache expert. Check out this link for more info http://httpd.apache.org/docs/current/mod/mod_rewrite.html
-
Oh man that would be great for the editor. I'm having to add a bunch of pivots to do a similar functionality, and it is terrible as far as keeping track of things.
-
Any update to this? I know you're super busy with the new UI.
-
See PM with link and instructions on how to reproduce.
-
It would be nice if Leadwerks had the ability to resize the map without having to export, then resize, then re-import.
- 1
-
My computer took a **** on me at the moment, I can get you GIT access right now,
or in a week I can get you a zip of the project.
Realtime Playing/Editing
in Suggestion Box
Posted
@josh. I wouldn't expect object scripts to be ran in edit mode, but to pause all execution of them, edit the map, then resume the scripts when the editing is finished.