Jump to content

micovery

Member
  • Content Count

    23
  • Joined

  • Last visited

  • Medals

Everything posted by micovery

  1. Made this simple online utility to convert Steam ID to BattlEye GUID. http://codepen.io/micovery/full/bNbLqL It's entirely JavaScript based. Here is the source if you are interested: var uid2guid = function(uid) { if (!uid) { return; } var steamId = bigInt(uid); var parts = [0x42,0x45,0,0,0,0,0,0,0,0]; for (var i = 2; i < 10; i++) { var res = steamId.divmod(256); steamId = res.quotient; parts[i] = res.remainder.toJSNumber(); } var wordArray = CryptoJS.lib.WordArray.create(new Uint8Array(parts)); var hash = CryptoJS.MD5(wordArray); return hash.toString(); }; It uses's crypto-js and BigInteger.js
  2. Hey All, I am the developer of the jni.dll extension, that brings support for the JVM in Arma 3. Check it out here if you have not already done so. While working on that extension, I felt the pain of the slow development cycle ... having to compile the Java code, rebuild jar files, restart the game, etc. I wanted to develop with something less "enterprisy", with faster turn-around, and more in-tune with the online community of developers. And so, I decided to bring Node.js in into the picture ... what is Node.js you ask? If you simply want to use JavaScript with your missions, then you should use Sima's JavaScript for Arma (@JS addon). With Node.js, on the other hand, you get the benefit of an extensive (and growing) set of community provided packages. The packages are available through the Node Package Manager (see https://npmjs.org). In fact, one of the main components of this release, is implemented as a node package itself. How it works It's just a simple client-server model between SQF side (client), and the Node.js side (server). On the SQF side, there is a library called sock.sqf On the Node.js side, there is a node package (sock-rpc), that allows you to setup an RPC (remote procedure call) server. The glue between these two, is a C/C++ extension called sock.dll. The extension transparently manages a TCP/IP socket connection to the remote server. It acts a middle man relaying the requests originating from the SQF code, and serving back the response of the "remote" side. Now, when I say "remote", I mean outside of the game. The extension is not intended to communicate with a truly remote (in another machine) Node.js server. If that's the case, then the network overhead can become unacceptable. As long as your "remote" side sits on the loop-back address (::1 or 127.0.0.1), then the communication never goes out of the TCP/IP stack. Prerequisites 1. Visual C++ Runtime (http://www.microsoft.com/en-us/download/details.aspx?id=26999) 2. Node.js (http://nodejs.org/download/) Components 1. sock.dll - This is a C/C++ extension that allows communication between SQF (using SOCK-SQF protocol), and a "remote" server (using SOCK-TCP protocol). 2. sock-rpc - This a Node.js module that implements the RPC server side, on top of the SOCK-TCP protocol 3. sock.sqf - This is small library that implements the RPC client side, on top of SOCK-SQF protocol What are those protocols: SOCK-SQF, and SOCK-TCP? ... you may be asking yourself. I made them up :), to describe the communication between the components. If you want to read more on them, jump to the documentation: SOCK-SQF Protocol, SOCK-TCP Protocol. Extension setup Place the sock.dll file in the Arma 3 directory (C:\Program Files (x86)\Steam\steamapps\common\Arma 3\) The extension reads configuration parameters from the Arma 3 process command line arguments. There are two required command line arguments: 1. -sock_host You must set this to the host name, or IP address of the "remote" server side (e.g. ::1) 2. -sock_port This is the port number of the "remote" server side. Server side model This can be any Node.js application using the "sock-rpc" module, to expose methods that can be invoked from SQF. The following example shows a simple RPC server with a "getDate" method, and an "echo" method. "use strict"; var rpc = require('sock-rpc'); /** * Echo back all arguments passed. * echo(...,callback); */ rpc.register("echo", function () { var args = Array.prototype.slice.call(arguments, 0); var callback = args.pop(); callback(null, args); }); /** * Get date (no arguments) */ rpc.register("getDate", function (callback) { callback(null, new Date().toString()); }); rpc.listen("::1", 1337); Client side model From the SQF code, you can use the function "sock_rpc", to send requests over to the "remote" Node.js side. //Example for using the sock_rpc function private["_method", "_response", "_params"]; _method = "getLocalTime"; _params = ["PST"]; _response = [_method, _params] call sock_rpc; if (isNil "_response") exitWith { player globalChat format["Error occurred while invoking the %1", _method]; } else { player globalChat _response; }; Data mapping Underneath it all, the sock.sqf library takes care of serializing your request into proper JSON that can be evaluated on the "remote" Node.js side. Also, on the way back, the sock-rpc Node.js module takes care of serializing the responses into SQF that can be compiled by the game engine. For most cases, SQF and JSON can be mapped back and forth pretty nicely (except when mapping objects). Here is the full details of the data mapping logic: //SQF to JSON mapping * SQF array, is mapped directly to JSON array * SQF number, is mapped directly to JSON number * SQF string, is mapped directly to JSON string (double-quotes escaped, i.e. "\"") * SQF nil, is mapped to JSON null * SQF objNull, is mapped to JSON null * SQF objects, are mapped to JSON object with the following fields: {"netId": "0:1", "name": "player1"} //JSON to SQF mapping * JSON array, is mapped directly to SQF array * JSON number, is mapped directly to SQF number * JSON string, is mapped directly to SQF string (double-quotes escaped, i.e. """") * JSON undefined, is mapped to SQF nil * JSON null, is mapped to SQF nil * JSON objects, are mapped to SQF code-block with the following structure: {[["key1", "value1"], ["key2", "value2"]]} Source Code Source is available in the following repositories: 1. Git repo for the sock.dll extension https://bitbucket.org/micovery/sock.dll/ 2. Git repo for the Noe.js sock-rpc server module https://bitbucket.org/micovery/sock-rpc 3. Git repo for the sock.sqf RPC client library https://bitbucket.org/micovery/sock-rpc.mission Demo Node.js Extension & Mission I have put together a mission to demo the setup of the Node.js sock-rpc server, and the sock.dll extension. You can read the full instructions for the setup, in the git repository for sock.sqf library itself. or, watch this video: Additional documentation The README files on the git repositories for each component contain: 1. Full API documentation 2. Protocol information, 3. How to enable debug, and logging levels Summary/Reflection Keep in mind that all the code is fairly new, and there will be bugs ... please report them, and I will try fix it on a timely manner. Or better yet, you can fix them and contribute back. What would you want to do with it? Let me know in this thread ... All of the code is under MIT license, enjoy. Cheers, micovery
  3. What is this ? It's a stats/persistence system for Linux or Windows Arma 3 dedicated server. The following database/storage systems are supported: MongoDB CouchDB Cassandra MySQL Redis File-System (if you don't have a database) At its core, the stats server exposes a key-value store that has this kind of structure: { "player1_id" : { "name": "player1", "money": 1000 }, "player2_id" : { "name": "player2", "money": 3000 } } Essentially, it is a big hash-map, with smaller nested hash-maps. The nested hash-maps are referred to as scopes. There is no limit to how many scopes you can have, or what a scope is. It's up to you. One possible design pattern is to have a scope for each player, using their UID as the scope name. Another pattern is to have a scope for each player/faction combination. (e.g. "player1_civ", "player1_bluefor", "player1_west", etc); The only restriction is that all scope names, and keys must be strings, but values can be pretty much anything (except an in-game object) Prerequisites Visual C++ Runtime (http://www.microsoft.com/en-us/download/details.aspx?id=26999) (if using Windows) lib32stdc++6 libc6-i386 lib32gcc1 (if using Linux) Node.js (http://nodejs.org/download/) Architecture It's made of three parts: Stats server, implemented using Node.js (source and documentation at: https://bitbucket.org/micovery/sock-rpc-stats) sock extension for Arma 3 (source and documentation at: https://bitbucket.org/micovery/sock.dll) Sample mission that contains the Client SQF API (source and documentation at: https://bitbucket.org/micovery/sock-rpc-stats.mission) The Client SQF API It has two main functions stats_set, and stats_get for setting, and getting key-value pairs Here are a few examples: //set key1,value1 within "scope" ["scope", "key1", "value1"] call stats_set; //set a single key-value pair ["scope", ["key1", "value1"]] call stats_set; //set multiple key-value pairs ["scope", ["key1", "value1"], ["key2", "value2"]] call stats_set; //get the value for "key1" ["scope", "key1"] call stats_get; //get the value for "key1", or return "default1" if not found ["scope", "key1", "default1"] call stats_get; //get the values for all keys within "scope" ["scope"] call stats_get; //get the values for "key1", "key2", and "key3" (note no default value given for "key3") ["scope", ["key1", "default1"], [key2, "default2"], ["key3"]] call stats_get; See the full Client SQF API documentation here. REPL for managing the key-value store Unless you know what you are doing, I would not recommend manipulating the data directly at the database level. To make the job easier, I have included an interactive REPL (Read-Eval-Print loop) that allows you to manipulate the data with simple set/get functions, in the same way as the Client SQF API. See the REPL documentation here. Fast read/write Once the data for a scope is read from the underlying storage system, it is cached in memory (until flushed). All read/write operations performed through the Client SQF API happen exclusively in-memory. By default, the data from memory is persisted to the underlying storage system every minute (you can modify the interval). However, it only persists the scopes that were modified in-memory since the last save. Automatic backups When the data for a scope is read from the underlying storage system, a backup is automatically created (you can disable this). This is mainly to help mitigate situations where a hacker tampers with the stats of the players in-game. The list of existing backups for a scope is kept within its meta-data. Server administrators can use the meta command in the REPL to view this information. The backups are stored in the same way as any other scope. The scope name for backups follows this format: originalScope + "." + timeStamp + ".bak" For now, restoring data from backup has to be done manually using the set/get commands. (I will be adding a restore command to the REPL to help with bulk restore). Extra goodies in the sample mission As proof of concept, I implemented a player stats system, and included it sample mission. The player stats system (pstats.sqf), saves the following information when a player disconnects: primary weapon (including items, and magazine with ammo count) secondary weapon (including items, and magazine with ammo count) handgun weapon (including items, and magazine with ammo count) position (above terrain level) stance damage fatigue goggles headgear assigned_items (Compass, GPS, Radio, Watch, Map, etc) backpack (with magazines and items) vest (with magazines and items) uniform (with magazines and items) Selected weapon The saved stats are by player UID, and faction. When the player reconnects, his faction specific stats are loaded, and restored. As long as the player is in-game, the saved stats will stay in memory (on the Node.js Stats Sever) ... but on-disconnect, his stats are flushed. Configuration Guide See the full instructions here for how to setup the Node.js Stats Server, the sock extension, and the sample mission. Here are a couple of demo videos I recorded following the steps in the configuration guide. First video shows me installing, and playing around with the REPL of the Node.js Stats server (connected to a remote MongoDB instance). Second video shows me configuring the Arma 3 dedicated server to use the sample mission, and sock extension for connecting to the Node.js Stats Server.
  4. I've been noticing that sometimes getPosATL gives me 1.#QNAN for the X, and Y coordinates. [1.#QNAN, 1.#QNAN, 0] I have not narrowed it down to know exactly when it happens. My first question here is: :icon_question: Is there any Arma 3 command I could use to reliably use to determine if a variable which is supposed to be a finite SCALAR is instead 1.#QNAN ? I am aware of this command: https://community.bistudio.com/wiki/finite But I have no way to test it, since I do not know how to artificially create a variable that has 1.QNAN value. I know that "NaN" stands for Not-A-Number ... so my second question is: :icon_question: What conditions are needed for a variable in SQF to end up being "1.QNAN" ? In other languages like JavaScript you can end up with "NaN" when doing arithmetic on values that are not numbers.
  5. Gotta play around more with extDB first, so that I can make a good side-by-side comparison. The main difference I believe is that extDB relies on having a pre-defined SQL schema, and queries, and procedures. Sock-rpc-stats on the other hand is schema-less ... which means it does not force a schema on you. However, at the end of the day ... the schema definition really lives in your mission code. For example, here is how I organized the information for the proof of concept player stats (pstats.sqf) that I included in the sample mission. { "76561198015751465_civ": { "createdAt_": 1413312842050, "updatedAt_": 1413313170677, "signature_": "gBV5BbuEFQDGR8q9JXS1fg==", "primary_weapon": "srifle_EBR_ACO_F", "primary_weapon_magazine": [ "20Rnd_762x51_Mag", 10, "true", 1, "srifle_EBR_ACO_F" ], "primary_weapon_items": [ "muzzle_snds_B", "", "optic_Arco" ], "secondary_weapon": "launch_I_Titan_short_F", "secondary_weapon_magazine": null, "secondary_weapon_items": [ "", "", "" ], "handgun_weapon": "hgun_Pistol_Signal_F", "handgun_weapon_magazine": [ "6Rnd_RedSignal_F", 4, "true", 2, "hgun_Pistol_Signal_F" ], "handgun_weapon_items": [ "", "", "" ], "pos_atl": [ 16081.4, 17047.8, 0.00139951 ], "dir": 259.019, "animation": "amovpercmstpsraswpstdnon", "damage": 0, "fatigue": 0, "uniform": "U_C_HunterBody_grn", "goggles": "G_Balaclava_combat", "headgear": "H_Booniehat_grn", "assigned_items": [ "ItemWatch", "ItemRadio", "ItemGPS", "Rangefinder" ], "backpack": "B_BergenC_blu", "vest": "V_Chestrig_blk", "magazines": [ [ "7Rnd_408_Mag", 7, "false", -1, "Vest" ], [ "20Rnd_762x51_Mag", 10, "true", 1, "srifle_EBR_ACO_F" ], [ "6Rnd_RedSignal_F", 4, "true", 2, "hgun_Pistol_Signal_F" ] ], "backpack_items": null, "vest_items": null, "uniform_items": null, "current_weapon": "hgun_Pistol_Signal_F" } } Ty, good idea ... though if you have too many mission variables, it can be hard to manage. But, it's still useful. A mission maker for example could add a command line argument like -foo=someFile.sqf. Then, as you pointed, he would ask for the value using regex, or a substring, and then read the referenced file itself from within the mission in SQF. The one problem with this is that you have to be careful to not expose the values of parameters like -config, and -profile ... that'd be a pretty bad security exposure. People could read the contents of your config files ...or, if they know the location where the BattleEye config file is stored, they could even probe until hit the "not-so-random" renaming of BEserver.cfg.
  6. Thanks for that! This project (sock-rpc-stats) is not specifically meant to be a replacement for Arma2Net. Its single purpose is to work as stats server, with a simple JSON abstraction for storing and retrieving data. You can think of it as an alternative to other persistence solutions like extDB, and iniDB. However, sock-rpc-stats is built on top of the sock-rpc Node.js module, which could technically be a replacement for Arma2Net extensions. I have released the sock-rpc module on a different thread over at Node.js Extension for Arma 3 (sock.sqf, sock.dll, sock-rpc). Here is a break-down of the main differences between Arma2Net, and sock-rpc. I've tried to make it as factual, and unbiased as possible. For folks who are knowledgeable about Arma2Net, feel free to correct me, whereever I make inaccurate statements (I will incorporate the corrections as edits). [table=align: left, class: grid, width: 1200] [tr] [th][/th] [th]Arma2Net[/th] [th]Node.js sock-rpc[/th] [/tr] [tr] [td=width: 150]Architecture[/td] [td]As I understand Arma2Net works as a bridge between C,C++ unmanaged land, and the .NET managed land. You have to write code, and compile it into a DLL. [/td] [td]RPC stands for: Remote Procedure Call. You are technically invoking remote JavaScript functions from within SQF. There is no compiling at all. You just make the code changes, and restart the RPC server. Meanwhile the game server itself can still be running.[/td] [/tr] [tr] [td]Language[/td] [td]You can use any language that can be compiled into Microsoft's Common Intermediate Language (see the list at http://en.wikipedia.org/wiki/List_of_CLI_languages)[/td] [td]It's a Node.js application, so you write the code in JavaScript. JavaScript, has been around since the release of Netscape Navigator 2.0 in September 1995 ... and nearly 20 years later, it's still going.[/td] [/tr] [tr] [td]callExtension buffer size limitation[/td] [td]In Arma 3, the callExtension response buffer size is 10240 bytes. With Arma2Net, I think you have to manually work-around this limitation. [/td] [td]When using sock-rpc, this is handled transparently for you. As a developer, you don't have to worry about it. You simply worry about writing your misison's SQF code, and JavaScript functions.[/td] [/tr] [tr] [td]Debugging[/td] [td] When using Arma2Net (or any extension), in Arma 3, debugging is not easy (at least on Windows). You have to have write print statements to trace the logic you are debugging. Back in Arma 2, you could attach Visual Studio to the game process, and load the symbols for the DLLs, and literally step through the extension code while the game was waiting for the callExtension invocation to exit. This does not work anymore in Arma 3, maybe the BIS developers have put some traps to prevent hackers from attaching debuggers to the game client. Today, once you attach a debugger to A3, and stop at a breakpoint ... the game simply crashes. In Linux, you can still attach GDB to the server process ... without it crashing. [/td] [td]With sock-rpc, debugging is a breeze, or as easy as in any Node.js application. Node.js (based on Google's V8 engine), comes with its own built-in debugger. You can start a node application in debug mode, and step through the code, or attach a remote debugger to it. Some popular ones are node-inspector (see ), and the debugger inside IntelliJ's WebStorm IDE (available at https://www.jetbrains.com/webstorm/) [/td][/tr] [tr] [td]Peformance[/td] [td]While Arm2Net acts a bridge, the performance of the callExtension invocations is not hindered much ... as the call never leaves the Arma process.[/td] [td]With sock-rpc, the calls technically exit the Arma process, and go over TCP to the RPC server Node.js process. This adds some overhead, however, when the RPC server listens on the loop-back address (127.0.0.1), most TCP stacks handle the routing internally, so it's not a big hit. I would not recommend running the RPC server on a different machine.[/td] [/tr] [tr] [td]Ease of use, and community support[/td] [td]Well, you have to know your way around the .NET libraries, and be able to write code in one of the CLI languages. There is a lot of community support, as .NET is very popular. Folks coming from a traditional OO (object oriented) background/education tend to gravitate towards this.[/td] [td]JavaScript is very easy to learn for beginners. There is no lack of support there either ... Node.js, though not as old as .NET, is very popular as well. Also, you get to re-use any NPM (https://www.npmjs.org/) module you want. [/td] [/tr] [tr] [td]Cross platform support[/td] [td]With Arm2Net, Windows is the main platform being targeted. Writing Arma2Net "addins" that work in Linux can be tricky. Not sure if anyone has gotten it work in Linux. Maybe using Wine, or mono?[/td] [td]sock-rpc supports both Windows, and Linux (sock.dll, and sock.so) ... your actual application code is in JavaScript which itself is platform agnostic. Node.js is officially supported on both Windows, and Linux (http://nodejs.org/download/)[/td] [/tr] [tr] [td]Addins support[/td] [td]This is a concept specific to Arma2Net. It supports bridging to multiple "addins"[/td] [td]sock-rpc does not have the concept of "addins" ... but does not mean it's not possible. You can technically expose functionality from multiple independent Node.js modules, by creating a wrapper module that "requires" the dependent modules, and registers their functions as RPC calls.[/td] [/tr] [tr] [td]Client side SQF libraries[/td] [td]With Arma2Net, you have to deal with the low-level "callExtension" calls directly.[/td] [td]sock-rpc provides a layer of abstraction with a single SQF function (sock_rpc) that you can call from anywhere (client or server). If invoked from client-side, the call is automatically routed to the server side, where the sock.dll/sock.so extension is normally installed.[/td] [/tr] [/table]
  7. Alright, so new release of sock-rpc-stats v0.0.5 now available on NPM Here is the change-log: 0.0.5 Defect: Fix major problem where the interval function was always disabled Defect: Fix issue with default values 0, and empty string, being treated as undefined [*] 0.0.4 Enhancement: add support for pop, push, shift, and unshift array operations Enhancement: add support for JavaScript/JSON dot notation on keys [*] 0.0.3 Defect: Fixed issue with line endings for Linux [*] 0.0.2 Enhancement: meta function added for viewing scope meta-data [*] 0.0.1 - Initial release Also, added support on the Client SQF API within the sock-rpc-stats.mission for the new array manipulation functions, as well as a wrapper/adapter for iniDB. That should make it easier to port missions that are using iniDB (I used that for Wasteland). Hopefully I can keep working more on tools for Arma 3 :) I took the conversation about porting Wasteland over to their forums ... please use this thread over there now: http://forums.a3wasteland.com/index.php?topic=565.msg3468#msg3468 I have forked their Wasteland Altis source, and ported it to use sock-rpc-stats with minimal changes.
  8. Ok, on the topic of porting Wasteland ... looks like iniDB has the concept of accessing separate files as independent databases, as well as a concept of sections within a database. In order to map that data model to the JSON data-model, I think easiest way would be to do something like this: { "database1": { "section1": { }, "section2": { } }, "database2": { "section1": { } } } This way each "database" becomes a scope, and the underlying sections become keys within the scope. In order to make it easier for manipulating data, and accessing the data ... I will add support for JavaScript style dot-notation, on stats_set, and stats_get function. e.g. ["player1", ".money.bank", 100] call stats_set; ["player1", ".money.cash", 200] call stats_set; ["player2", ".vest.items[0]", "ItemRadio"] call stats_set; Would turn into: { "player1": { "money": { "bank": 100, "cash": 200 } }, "player2": { "vest": { "items": ["ItemRadio"] } } } I also noticed that iniDB has a function for deleting a database ... which seems kind of dangerous to me, even with backups enabled. So I think I will not allow an entire scope to be deleted. However, a "section" under a scope can be deleted simply by setting it to nil like this. ["database", "section1", nil] call stats_set; I'll update this thread once I make the "dot-notation" improvement to the Node.js module. I will need with provisioning a box to host the wasteland mission for live testing.
  9. Thanks, I have not integrated it with Wasteland ... but it should be technically feasible. I can lend some help. Where do I grab the wasteland mission from, is it this: https://github.com/A3Wasteland/Release_Files ? Edit: Going through the source, seems that it would not be too complex. Looks like it;s using iniDB, and all calls for set/get values go through two main functions: iniDB_read; initDB_write; I think that all it would take would be to take the functions in the file: fn_inidb_custom.sqf, and simply forward the calls to stats_get, and stats_set as needed (I could be underestimating the work).
  10. Thanks Tupolov. Been checking out the ALiVE mod, looks awesome.
  11. New versions of both the sock-rpc Node.js module, and the Arma 3 sample mission are now available. (v1.0.0, and v.0.0.2 respectively) Server side changes On the server side, the callback mechanism for the JavaScript RPC functions has changed. The callback function is now passed as the last argument. If you are expecting variable arguments, in your RPC function, you must pop the last argument to get the callback. e.g. rpc.register("echo", function () { var args = Array.prototype.slice.call(arguments, 0); var callback = args.pop(); callback(null, args); }); Also, notice when invoking the callback, the signature is now: callback(err, result) This is more in-line with the callback standards used throughout Node.js. Client side changes On the client side, I have improved the sock.sqf library to allow calling the sock_rpc function from client-side SQF as well. Behind the scenes, it uses publicVariableServer, and publicVariableClient to pass the request, and response around. The one caveat is that when invoking the sock_rpc function client-side SQF, you have to do it within a scheduled environment, as it uses SQF sleep to wait for the server's response. e.g. [] spawn { private["_response"]; _response = ["echo", ["arg1", "arg2"], false] call sock_rpc; diag_log _response; }; If you are invoking the sock_rpc function on the server side, the "scheduled environment" restriction does not apply.
  12. I have ported the library to Linux. If you want to build it yourself, on Ubuntu 14.04 (64bit): sudo apt-get update sudo apt-get install git build-essential g++-multilib git clone [url]https://micovery@bitbucket.org/micovery/sock.dll.git[/url] cd sock.dll make If you want to use the pre-buit binary, on Ubuntu 14.04 (64bit): sudo apt-get install lib32stdc++6 libc6-i386 lib32gcc1 wget https://bitbucket.org/micovery/sock.dll/raw/v0.0.2/Release/sock.so It's nearly the exact same code-base as the windows version. (just added a few #ifdef __linux here and there). I did a bit of testing on the Linux version to make sure it actually worked, but that was pretty much it. Enjoy
  13. Great that you got it working! I've never setup Arma 3 server in a linux box, but I at home programming in linux, and sticking to POSIX. I'll give these instructions a try this weekend: https://community.bistudio.com/wiki/Arma_3_Dedicated_Server#Instructions_.28Linux_o.2Fs.29 If it works well, then you can have a sock.so lib soon :)
  14. That's awesome. I saw a post about the cheap SSL on hacker news (https://news.ycombinator.com/) the other day and was going to post back here. Looks you are were much ahead :-)
  15. Pretty nice! Good job. I have couple of security concerns, and user experience suggestions. 1. Enable HTTPS (Even this forum is using HTTP, so I can't safely use it on public networks) 2. Use OpenID connect, and store minimal amount of personal user information 3. The squad xml URL should be a first class item in the UI experience. Looks like it's tucked away within the members panel.
  16. Thanks! The sock.dll extension, and the sock.sqf library manage that transparently for you ... I have documented the internals at https://bitbucket.org/micovery/sock.dll#markdown-header-sock-sqf-protocol ... You can pretty much retrieve any size response (or rather, however long is the maximum you can fit inside an SQF string)
  17. Not as it is right now. The C extension has some Windows specific code for benchmarking, error handling, and socket initialization. The rest is mostly just posix, so it should be straight-forward to port it for building an *.so. UPDATE/EDIT: Created an enhancement ticket over at the repository. If you are interested, I can work on it, but will need an environment to test the extension. Or at least some assistance on how to setup the game server in Linux. https://bitbucket.org/micovery/sock.dll/issue/1/add-support-for-linux
  18. Hey All, I am the developer of the persistence framework for Arma 2: Takistan Life Revolution mission (which would save data such as position, gear, clothes, etc). For that mission, I developed a C extension that could invoke Java code. From the Java side, it would then persist the player's data points to xml files. Later we switched the storage from plain files, to a relational database. Anyways, I thought it would be good to contribute back to the Arma community by sharing the source code of the C extension, and a couple of Java classes that can be used as a starting point for all sorts of fancy Java extensions. Prerequisites 1. Visual C++ Runtime (http://www.microsoft.com/en-us/download/details.aspx?id=26999) 2. Java 7 Runtime Environment (JRE) (http://www.oracle.com/technetwork/java/javase/downloads/index.html) Components 1. jni.dll - This dll is a C extension that uses the Java Native Interface (JNI) to instantiate a Java Virtual Machine (JVM), and invoke a method with the signature: "public static String run(String arg)" 2. jni.conf - This is a configuration file which is read by jni.dll to configure the Java Runtime Environment (JRE) 3. RVExtension.jar - This is a jar file containing the main class file which has the "run" that is invoked by the C extension. Configuration The jni.dll takes its configuration from one file named "jni.conf". This file must be located in the Arma 3 process working directory (i.e. C:\Program Files (x86)\Steam\steamapps\common\Arma 3). The jni.conf configuration file requires that you have the following 3 variables defined: 1. JAVA_HOME You must set this environment variable to the location where your JRE is installed. e.g. JAVA_HOME=C:\Program Files (x86)\Java\jre7 2. CLASSPATH This is the usual Java CLASSPATH variable. You can have one or more jars in the classpath, or plain directories with classes in them. e.g. CLASSPATH=.\RVExtensionDemo.jar 3. MAINCLASS You must set this to the fully qualified name (including package) of your main Java class. This class must contain a method with the following signature "public static String run(String arg)". e.g. MAINCLASS=com.micovery.RVExtensionDemo This class must be available through the CLASSPATH specified on #2. Runtime Execution Flow When the C extension is invoked from SQF, for example: "jni" callExtension "Hello World"; It invokes the "run" method from the class you specified in your jni.conf, and passes the "Hello World" argument to it. Whatever string the "run" method returns, is then passed back to Arma 3, and thus available as the return value of the SQF call. Source Code You can view the source in the following repositories: https://bitbucket.org/micovery/rvextensiondemo.eclipse/ https://bitbucket.org/micovery/jni.dll I have put both Eclipse, and Visual Studio projects in there. Demo Java Extension & Mission I have put together a demo Java extension, and demo mission using the jni.dll extension. The binaries for the C extension, and the jar file can be found in: https://bitbucket.org/micovery/rvextensiondemo.mission Instructions: 1. Place all three files: jni.dll, RVExtensionDemo.jar, and jni.conf in your Arma 3 directory. 2. Place the RVExtensionDemo.Statis.pbo in your MPMisisons directory Decription of the demo: This demo is using JAXB to unmarshall (deserialize) XML that is generated on the SQF side describing a method invocation. For example, the following XML: <MI> <M>date</M> <AL> <A>yyyy/MM/dd HH:mm:ss</A> </AL> </MI> Describes a method invocation (<MI>), for the "date" method (<M>), with the arguments list (<AL>), containing one argument (<A>) with value of "yyyy/MM/dd HH:mm:ss". From SQF, the call would look like this: "jni" callExtension "<MI><M>date</M><AL><A>yyyy/MM/dd HH:mm:ss</A></AL></MI>" This instructs the "run" method on the demo Java extension to invoke the method with the following signature "String date(String arg)". On the Java side, after unmarshaling the XML, the actual invocation is done using reflection. Debugging and Troubleshooting the C Extension The jni.dll extension creates a log file called "jni.log" in the same location where the "jni.conf" file is located. The log file contains detailed information about the work being done by the jni.dll itself. 1. It logs all the variables loaded from jni.conf, and will tell you if you are missing a required variable. 2. It logs if there are errors when instantiating the JVM, or if there are errors finding the MAINCLASS, or if the MAINCLASS does not contain the prescribed "run" method. 3. It logs trace information for every call made to the jni.dll showing the input and output. (This is useful for development, but not good for production) Debugging and Troubleshooting the Java code There is an optional variable you can set in "jni.conf" called JDWP_ADDRESS. This variable allows you to set the "-Xrunjdwp" initialization argument for the JVM. For example: JDWP_ADDRESS=50050 Would set the following initialization argument for the JVM -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=50050 Which would allow you to remotely attach a Java debugger to the process. Summary/Reflection I am just providing the basic building blocks. Hopefully the Java developers within the Arma community can see the potential for doing more interesting things with this. I will be releasing later on the full source code for the stats persistence Java extension that drove me to write this in the first place. It uses OpenJPA to interact with any relational database you want. Cheers, micovery
  19. I am aware. I wrote this originally because I needed it for Arma 2, which did not have any official Java support. It looks to be the same for Arma 3 so far. A. With the existing functionality, it would have to be asynchronous ... using events, and callbacks. There would have to be an event loop on the SQF side, that would periodically call Java to pop events from a queue and perform the needed SQF calls. Then SQF would have to call Java to put back the response on another queue, for the Java side to pickup. B. JNI can go both ways, you can invoke C code from Java side as well. BIS could provide us with a way to directly invoke the SQF commands from C itself. Then wrapping those calls with JNI becomes trivial, and you can directly call those methods from Java.
  20. I am trying to add weapons specifically inside a player's vest or uniform. The game UI dialog allows you to drag a weapon from a crate and put it inside one of the player's containers (uniform, vest, or backpack). I can't figure out how to do this from a script. I already know how to add a weapon to the player's backpack like this: (unitBackpack player) addWeaponCargoGlobal ["hgun_P07_F", 1]; However ... there are no equivalent commands like: (unitVest player) addWeaponCargoGlobal ["hgun_P07_F", 1]; (unitUniform player) addWeaponCargoGlobal ["hgun_P07_F", 1]; Any help is appreciated. Cheers
  21. Thanks for the replies. Well, it seems that there is no way to do this at the moment. I am aware you can add items, to the inventory, and they get distributed according to the mass of the item, and the maximum load of the containers. The question was specifically for weapons.
  22. Hi All, I am running Arma 2 OA server using 1.62.96493 patch version. The server crashed, and created the minidump, as well as other debugging information. How do I go about reporting this crash? Who do I send the minidump, and log files to ... so that this crash can be fixed? The crash has happened only once since I started using the server last night ... so I am not sure how consistent it is ... or what the exact reproduction conditions are. Hopefully I am posting in the right forum for this issue. If not, please advise where to seek help.
×