code34 248 Posted December 27, 2013 (edited) Bus message exchange This package builds a main BUS messages between clients & server and optimize data transfert between clients & server Feature: - build one main bus message exchange that is better against the red chain - Mp & SP compatible - send & listener oriented Information: This script is a part of the handler modules from WIT - ARMA2. All modules/functions of handler modules from WIT are not distribute in this package. Download: https://www.dropbox.com/s/s80fd7xi8df7dif/bus_message_exchange.Altis.zip?dl=0 Github: https://github.com/code34/bus_message_exchange.Altis Licence: Under Gpl, you can share, modify, distribute this script but don't remove the licence and the name of the original author Readme: /* Author: code34 nicolas_boiteux@yahoo.fr Copyright © 2013 Nicolas BOITEUX Bus Message Exchange (BME) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ Create a main bus message between clients & server Usage: put the directory BEM in your mission directory put this code into your mission init.sqf call compilefinal preprocessFileLineNumbers "BME\init.sqf"; See example mission in directory: bus_exchange_message.Altis Licence: You can share, modify, distribute this script but don't remove the licence and the name of the original author logs: 0.3 - Fix: - fix mp handler call - fix reset code 0.2 - Fix: - add performance improvement of @Prodavec - add private variable declaration - fix iteration call - add logs - change calling line 0.1 - BUS message Exchange original from A2 - Warcontext Documentation V 0.3 : BME by code34 - nicolas_boiteux@yahoo.fr V 0.2 : BME by code34 - nicolas_boiteux@yahoo.fr V 0.1 : BME by code34 - nicolas_boiteux@yahoo.fr Messages are variables that contains value, and are send to destination host. How to send message: -------------------- Usage: [message, destination] call BME_fnc_publicvariable; Send a message to all client ["variablename", "client"] call BME_fnc_publicvariable; Send a message to a specific client ["variablename", "client", clientid] call BME_fnc_publicvariable; Send a message to server ["variablename", "server"] call BME_fnc_publicvariable; Send a message to everybody ["variablename", "all"] call BME_fnc_publicvariable; How to receive message: ----------------------- The message are handle by listeners on client or server side. Listeners are specific functions that are executed on destination host, when message is distributed. Message is distributed as a parameter of the function like eventhandler do. There is tow kind of listeners: - server listeners - client listerners The listener declaration must respect this syntax: BME_netcode_server_nameofyourvariable = { code to execute on server side }; BME_netcode_nameofyourvariable = { code to execute on client side }; You can declare thoses listeners directly on your code, but it's more simple to use the default location: client side: - declare by default in BME_clienthandler.sqf server side: - declare by default in BME_serverhandler.sqf exemple to hint a message to all client (listener already exists :) ) bme_message = "Hello folks!"; ["bme_message", "client"] call BME_fnc_publicvariable; Example of server listener to init a variable on server side client side: myvariable = "Hello folks!"; ["myvariable", "server"] call BME_fnc_publicvariable; server side BME_netcode_server_myvariable = { myvariable = _this select 0; }; Example of client listener to init a variable on client side server side: myvariable = "Hello folks!"; ["myvariable", "client"] call BME_fnc_publicvariable; client side BME_netcode_myvariable = { myvariable = _this select 0; }; Edited January 27, 2015 by code34 Share this post Link to post Share on other sites
mariodu62 5 Posted December 28, 2013 Hi Nicolas, Can you tell us the difference between this function and bis_fnc_mp ? Share this post Link to post Share on other sites
code34 248 Posted December 28, 2013 (edited) I don't know cause i don't use packaged BIS functions since Arma: too much side effect and we don't have access to all the code. This system works since A2, BIS certainly decided to copy it and generalize it in A3, as they already did with other modules like Alice, etc in A2 :) I release thoses scripts cause i had to make them standalone for my other missions. :D Note: i developped this script as workaround cause there is a lack with the MP DATA transfert/refresh design in main game, and also with publicvariable function in local. Edited December 28, 2013 by code34 Share this post Link to post Share on other sites
Guest Posted December 28, 2013 Release frontpaged on the Armaholic homepage. Bus Message Exchange (BME) v0.1 ================================================ We have also "connected" these pages to your account on Armaholic. This means in the future you will be able to maintain these pages yourself if you wish to do so. Once this new feature is ready we will contact you about it and explain how things work and what options you have. When you have any questions already feel free to PM or email me! Share this post Link to post Share on other sites
Gudsawn 93 Posted December 28, 2013 Can you explain a bit more about what this actually is, and where it should be used? Share this post Link to post Share on other sites
rakowozz 14 Posted December 28, 2013 Looks good! How can I monitor, not necessarily with this tool, the data transfer performance within a mission/server? I'm concerned with the use of publicVariables, in particular. Share this post Link to post Share on other sites
code34 248 Posted December 28, 2013 Can you explain a bit more about what this actually is, and where it should be used? Hi, I think the best exemple is the hello world ;) this code on server part: myvariable = "Hello folks!"; ["myvariable", "client"] call BME_fnc_publicvariable; print hello world on all the client, this function should be declare on client part: BME_netcode_myvariable = { myvariable = _this select 0; hint myvariable; }; same thing but inverse way this code on client side: myvariable = "Hello folks!"; ["myvariable", "server"] call BME_fnc_publicvariable; this code on server side to print into logs BME_netcode_server_myvariable = { myvariable = _this select 0; diag_log myvariable; }; ---------- Post added at 17:16 ---------- Previous post was at 17:12 ---------- Looks good!How can I monitor, not necessarily with this tool, the data transfer performance within a mission/server? I'm concerned with the use of publicVariables, in particular. You can not monitor the data transfert performance with this tool ;( Share this post Link to post Share on other sites
Prodavec 10 Posted December 30, 2013 (edited) OMG, this is ONE MORE Client <-> Server exchanging system. I thought there's REALY some optimizing code but not. 1. init.sqf [] execVM "BME\init.sqf"; Using execVM may cause loading order issues, like it was in Warfare by Benny for example. And it's better to send null-pointer instead of empty array if you don't want to send eny kind of arguments: objNull call compile preprocessFileLineNumbers "BME\init.sqf"; It guarantees loading order before any user script which are using that system. 2. BME\init.sqf _garbage = [] spawn BME_fnc_queue; _garbage = [] call BME_fnc_eventhandler; _garbage = [] call BME_fnc_serverhandler; Same: use objNull. And... where is local var privatization? If you create local var _myvar, always add it to private block: private "_myvar"; It'll be very bad if someone will create "_garbage" var and BME will be loaded between user scripts. _garbage variable value will be overrided with a script handle. Should be fixed with: private "_garbage"; 3. \BME\BME_queue.sqf waituntil {(count bme_queue) > 0}; WOW! ARE YOU KIDDING ME? Oh yeah, I know the idea: LAGS FOR EVERYONE FOR FREE :)))) Not realy. And then people would curse BIS for laggy scripts / low FPS / etc. Very "nice" solution for ArmA servers. First off you MUST to know: waitUntil works on full speed 1 check per frame in non-scheduled environment but may be delayed. If you're using waitUntil with no delay it completely loads VM with useless work (most of loops have very low efficiency by design) in most of time. The VM's script scheduler will allocate its time between useless FAST loop and other scripts. Is it good? That part of the code should be recoded with no loop. 4. \BME\BME_queue.sqf if((_type == "server") or (_type == "all")) then It's much better to compare vars by float/double values instead of strings. So if ("aaaa" == "bbbb") then {...}; if ("someshit" == "someshit") then {...}; works much slower (depending on the strings size) than this: if (var1 == var2) then {...}; if (_shit1 == _shit2) then {...}; and it'll be better way to use macro instead creating local var for comparing: #define DO_SOME_SHIT 100 #define DO_OTHER_SHIT 101 switch (_input) do { case DO_SOME_SHIT: { // ... }; case DO_OTHER_SHIT 101: { // ... }; }; // ... ["Hello World!", DO_SOME_SHIT] call fnc_MyShit; 5. \BME\BME_queue.sqf call compile format["wcgarbage = [_variable] spawn BME_netcode_server_%1;", _variablename]; OMG! You're using slow dynamic compilation instead of getting direct access to the var! Why? objNull spawn (missionNamespace getVariable (format ["BME_netcode_server_%1", _variablename])); Is wcgarbage var used elsewhere? bme_queue select 0 bme_queue select 0 bme_queue select 0 Any reason to extract the array entry three times instead of using single-time extraction and storing it in local var? 6. \BME\BME_eventhandler.sqf if!(tolower(_type) in ["client", "server", "all"]) exitwith {hint "BME: wrong destination parameter should be client|server|all"}; ... switch (tolower(_type)) do { case "server": { _variablevalue = call compile format["%1", _variablename]; See above. If you will use macros, toLower will not be used. (((bme_addqueue select 2) == "server") or ((bme_addqueue select 2) == "all"))) (((bme_addqueue select 2) == "client") or ((bme_addqueue select 2) == "all"))) Cool. "bme_addqueue select 2" is used FOUR times instead of ONE. bme_queue = bme_queue + [bme_addqueue]; Why would you use binary addition instead of set? bme_queue set [count bme_queue, bme_addqueue]; Also there's no something revolutionary to decrease network traffic, something like serializing arrays (I hope you know about arrays trasfered via net ;) click). Thanks for your time, that was a nice try, but for actual use it should be completely rewritten from the scratch. For mission/addon makers I dont recommend to use it because of explained reasons. Use BIS_fnc_MP instead or create new one with no gross errors in simple code. Also that article is very usefull for novices: http://community.bistudio.com/wiki/Code_Optimisation Edited December 30, 2013 by Prodavec Share this post Link to post Share on other sites
code34 248 Posted December 30, 2013 (edited) Well provadec you spend a lot of energy to wrote this thread. You did some good remarks(that i will integrate in next release) and some wrongs cause you are not looking all the problem. But i think your global interest is about performance and how increase performance execution. First you must don't forget BME was developped on A2. Must of the execution time problem that your are talking about like array serialization happen at a low level design. Fix them by script is simply workaround, but it's not the good way to adress thoses kind of problem. Unfortunately, it's the way that BIS took for a lot of problem, but it made some shits over shit. My personnal thinking is about to produce a understandable code for me(as you did) that can be modify by other for their own purpose (you) that is most important than produce a code that win 0.000001ms at execution. Moreover, you must don't forget that messages transmist between client & servers happen at a low frequency that why it's not make sens to improve queue performance as it could be interesting to fix the array serialization you are talking about. Just for my personnal information cause you compare BIS_fnc_MP to BME, where do you find the BIS server side code of BIS_fnc_MP ? Edited December 30, 2013 by code34 Share this post Link to post Share on other sites
iceman77 18 Posted December 30, 2013 Thanks for taking the time to make this project code34. Share this post Link to post Share on other sites
mariodu62 5 Posted December 30, 2013 Interresting Prodavec but maybe too much Shit in your examples... Share this post Link to post Share on other sites
iceman77 18 Posted December 30, 2013 OMG, this is ONE MORE Client <-> Server exchanging system. I thought there's REALY some optimizing code but not.WOW! ARE YOU KIDDING ME? You're using slow dynamic compilation instead of getting direct access to the var! Why? Use BIS_fnc_MP instead or create new one with no gross errors in simple code. Using tact is always good. Other than that, thanks for the insights. Share this post Link to post Share on other sites
code34 248 Posted December 30, 2013 (edited) Release 0.2 :) - add performance improvement requests of @Prodavec - add private variable declaration - fix iteration call - add logs - change calling line https://www.dropbox.com/s/s80fd7xi8df7dif/bus_message_exchange.Altis.zip Edited December 30, 2013 by code34 Share this post Link to post Share on other sites
Guest Posted December 30, 2013 Updated version frontpaged on the Armaholic homepage. Bus Message Exchange (BME) v0.2 ================================================ We have also "connected" these pages to your account on Armaholic. This means in the future you will be able to maintain these pages yourself if you wish to do so. Once this new feature is ready we will contact you about it and explain how things work and what options you have. When you have any questions already feel free to PM or email me! Share this post Link to post Share on other sites
code34 248 Posted November 5, 2014 Hi Guys :) I just release the 0.3 version which fixes a broken code 0.3 - Fix: - fix mp handler call - fix reset code https://www.dropbox.com/s/y861wlhvjfmba70/bus_message_exchange.altis.pbo?dl=0 Share this post Link to post Share on other sites
mikie boy 18 Posted November 5, 2014 @code34 - nice work mate - MP coding is a bitch to start off with, so nice one on trying to simplify it for other users. I can see this being a big advantage for the wider audience with less coding knowledge. Found that many people in the Arma world want to make MP games straight away with little understanding, so hopefully this will assist them. Prodavec made one or two valid points about performance which hopefully you updated in your newest code. So all in all - nice work, and hopefully you can keep updating and simplifying for others. Share this post Link to post Share on other sites
Guest Posted November 6, 2014 Updated version frontpaged on the Armaholic homepage. Bus Message Exchange (BME) v0.3 ================================================ We have also "connected" these pages to your account on Armaholic. This means soon you will be able to maintain these pages yourself if you wish to do so. Once this new feature is ready we will contact you about it and explain how things work and what options you have. When you have any questions already feel free to PM or email me! Share this post Link to post Share on other sites
ozdeadmeat 12 Posted January 26, 2015 Ive been staring at this for 2 days. I can't make it work with my dedicated server. Can we get some doco explaining EXACTLY what one needs to do to make it work to a single client. For example. Send a location and direction to a single player onplayerconnected. Any help would be EXTREMELY appreciated. Share this post Link to post Share on other sites
code34 248 Posted January 27, 2015 (edited) hi :) I reverse the example of first page example of client listener to init a variable on client side server side: myvariable = [[16000, 16000], 0]; ["myvariable", "client"] call BME_fnc_publicvariable; client side BME_netcode_myvariable = { _myvariable = _this select 0; _position = _myvariable select 0; _dir = _myvariable select 1; }; Edited January 27, 2015 by code34 Share this post Link to post Share on other sites
code34 248 Posted October 20, 2017 just comit the fix from combat assault that were done during last years. you can retrieve them at this url: https://github.com/code34/bus_message_exchange.Altis this code is now longer maintained. BME2 is avalaible at this place: 1 Share this post Link to post Share on other sites