[New G2O][Shared] packetListener - Patrix - 04.06.2018
*Introduction:
NOTE! This script allows you to bind ONE function to listen packet with specific id.
NOTE! You have to specify packet id(s) by yourself in messageid.nut file
NOTE! Default packet Id type is Uint16, but you can change this easily by editing packetListener.nut script
NOTE! If you decide to test this script, make sure that you don't have any function(s) bind to onPacket event
Info: This script is stable and propably doesn't have any bugs.
Hi, as you know G2O allows you to communicate with client or server using packets, but if you want to split functions which are reading packets,
you still must have ONLY one onPacket event, in which you are reading packet id. If you have more complex scripts, it's not good to read a code
from file to file, so i've made very simple handler, which allows you to bind ONE function to specific packet id. Feel free to use it.
License
Download
*List of functions:
void addPacketListener(mixed packetId, func callback)
void removePacketListener(mixed packetId)
*Function (addPacketListener, removePacketListener) parameters description:
Info: packetId is "mixed" because it's up to you what packet id type will be (default is Uint16).
// Required parameters for addPacketListener
mixed packetId // The packetId, (it's recommended to specify packet Id's in file messageid.nut)
void callback // The function which will be called, when packet arrived to specific site.
// Required parameters for removePacketListener
mixed packetId // The packetId
*Installation:
1.Download zip archive
2.Unpack archive and place network folder in your G2O server directory wherever you want.
3.Add this line to parsed xml file, (for example: config.xml)
PHP <import src="network/network.xml" />
4.After that, you've loaded both scripts: (packetListener.nut and messageid.nut) to client-side and server-side.
*Examples:
*Sending client-side statistics to server, which can be later used for building an anti-cheat:
*Client-side:
Squirrel Script // creating infinite timer which will be called with one second delay setTimer(function() { local packet = Packet() // creating packet packet.writeUint16(PACKET.ID) // writing some id from messageid.nut, you have to define id yourself, it's only a dummy example packet.writeInt32(getPlayerStrength(heroId)) // writing player strength packet.writeInt32(getPlayerDexterity(heroId)) // writing player dexterity packet.send(RELIABLE_ORDERED) // sending packet to server }, 1000, -1)
*Server-side:
Squirrel Script addPacketListener(PACKET.ID, function(pid, packet) // binding function to packet with id PACKET.ID { local strength = packet.readInt32() // reading player strength local dexterity = packet.readInt32() // reading player dexterity if (strength != getPlayerStrength(pid)) // comparing client-side strength with server-side strength { ban(pid, -1, "Cheating strength") // givining permanent ban for cheating } else if (dexterity != getPlayerDexterity(pid)) // comparing client-side dexterity with server-side dexterity { ban(pid, -1, "Cheating dexterity") // givining permanent ban for cheating } })
*Sending server-side custom player class to client
*Server-side:
Squirrel Script local heroClass = { health = 1000, mana = 100, strength = 200, dexterity = 200 } addEventHandler("onCommand", function(pid, cmd, params) { if (cmd == "giveclass") // if player type /giveclass command, then.. { local packet = Packet() // creating packet packet.writeUint16(PACKET.CLASS) // writing some id from messageid.nut, you have to define id yourself, it's only a dummy example packet.writeInt32(heroClass.health) // writing class health packet.writeInt32(heroClass.mana) // writing class mana packet.writeInt32(heroClass.strength) // writing class strength packet.writeInt32(heroClass.dexterity) // writing class dexterity packet.send(pid, RELIABLE_ORDERED) // sending packet to client } })
*Client-side:
Squirrel Script addPacketListener(PACKET.ID, function(packet) // binding function to packet with id PACKET.ID { local health = packet.readInt32() // reading class health local mana = packet.readInt32() // reading class mana local strength = packet.readInt32() // reading class strength local dexterity = packet.readInt32() // reading class dexterity setPlayerHealth(heroId, health) setPlayerMaxHealth(heroId, health) setPlayerMana(heroId, mana) setPlayerMaxMana(heroId, mana) setPlayerStrength(heroId, strength) setPlayerDexterity(heroId, dexterity) })
*Examples comment
Example nr 2:
This is only a dummy example, to illustrate how addPacketListener function works.
If you really want to create a script which give some class to player, i recommend you to
giving statistics on server-side, because this example is not safe.
RE: [New G2O][Shared] packetListener - Tommy - 20.06.2018
Good idea, but personally I think that the g2o packages are enough and do not require any improvements, look at the fragment of my code and see that it's enough (I do not want you to treat it as hatred)
Squirrel Script enum packetList { option_lineChat, option_hud, option_password, option_notifications, id = 255 }; class PlayerOptions { constructor(server){ SCore = server; SPlayer = server.SPlayer; } function changeLine(pid, lines) { mysql_query(SCore.handler, "UPDATE options SET `chat_lines` = '"+lines+"' WHERE `login` = '"+SPlayer[pid].login+"'"); } function changeHud(pid, layout) { mysql_query(SCore.handler, "UPDATE options SET `hud_layout` = '"+layout+"' WHERE `login` = '"+SPlayer[pid].login+"'"); } function changePassword(pid, oldPass, newPass) { local result = mysql_query(SCore.handler, "SELECT * FROM players WHERE `login` = '"+SPlayer[pid].login+"' AND password = '"+crypt(oldPass)+"'"); if(result) { local row = mysql_fetch_assoc(result); if(row) { mysql_query(SCore.handler, "UPDATE players SET `password` = '"+newPass+"' WHERE `login` = '"+SPlayer[pid].login+"'"); } mysql_free_result(result); } } function changeNotifications(pid, notification) { mysql_query(SCore.handler, "UPDATE options SET `notification` = '"+notification+"' WHERE `login` = '"+SPlayer[pid].login+"'"); } function receivedPacket(pid, packet) { if(packet.readUInt8() == packetList.id) { switch(packet.readUInt8()) { case packetList.option_lineChat: changeLine(pid, packet.readInt8()); break; case packetList.option_hud: changeHud(pid, packet.readInt8()); break; case packetList.option_password: changePassword(pid, packet.readString(), packet.readString()); break; case packetList.option_notifications: changeNotifications(pid, packet.readBool()); break; } } } SCore = null; SPlayer = null; }
RE: [New G2O][Shared] packetListener - Patrix - 20.06.2018
Well, your code is pretty simple and readable, but this:
Squirrel Script function receivedPacket(pid, packet) { if(packet.readUInt8() == packetList.id) { switch(packet.readUInt8()) { case packetList.option_lineChat: changeLine(pid, packet.readInt8()); break; case packetList.option_hud: changeHud(pid, packet.readInt8()); break; case packetList.option_password: changePassword(pid, packet.readString(), packet.readString()); break; case packetList.option_notifications: changeNotifications(pid, packet.readBool()); break; } } }
Can cause problems because in this method, you are reading first packet value, I belive that you connect this method to onPacket event.
So, what if you have more similar functions/methods, and trying to read packet id in this way:
Squirrel Script if(packet.readUInt8() == packetList.id)
Even if this condition won't pass, you still read first value from packet, which was id.
Take a look at this code:
https://www97.zippyshare.com/v/LxAq6iiv/file.html
To simply avoid this problem, you must have ONLY ONE function connected to onPacket event on each side, then ONLY ONCE read packet Id, and check which function should be called based on it's value.
Even if you try to call two diffrent functions and pass them a packet object, it won't work, because this function will be working with an object reference, not it's copy.
In my opinion, this simple script makes it a little bit easier to add some new function(s) to call when packet with specific id arrive to it's location, but it's only my opinion, maybe i'm wrong .
RE: [New G2O][Shared] packetListener - Tommy - 20.06.2018
(20.06.2018, 17:26)Patrix Wrote: Well, your code is pretty simple and readable, but this:
Squirrel Script function receivedPacket(pid, packet) { if(packet.readUInt8() == packetList.id) { switch(packet.readUInt8()) { case packetList.option_lineChat: changeLine(pid, packet.readInt8()); break; case packetList.option_hud: changeHud(pid, packet.readInt8()); break; case packetList.option_password: changePassword(pid, packet.readString(), packet.readString()); break; case packetList.option_notifications: changeNotifications(pid, packet.readBool()); break; } } }
Can cause problems because in this method, you are reading first packet value, I belive that you connect this method to onPacket event.
So, what if you have more similar functions/methods, and trying to read packet id in this way:
Squirrel Script if(packet.readUInt8() == packetList.id)
Even if this condition won't pass, you still read first value from packet, which was id.
Take a look at this code:
https://www97.zippyshare.com/v/LxAq6iiv/file.html
To simply avoid this problem, you must have ONLY ONE function connected to onPacket event on each side, then ONLY ONCE read packet Id, and check which function should be called based on it's value.
Even if you try to call two diffrent functions and pass them a packet object, it won't work, because this function will be working with an object reference, not it's copy.
In my opinion, this simple script makes it a little bit easier to add some new function(s) to call when packet with specific id arrive to it's location, but it's only my opinion, maybe i'm wrong . If you write a structured script, it can be useful, but when it comes to oop, g2o packages are enough in this state and you really have to try to make a mistake(I think so). In any case, it can be useful for someone
Squirrel Script enum packetList { option_lineChat, option_hud, option_password, option_notifications, id = 255 };
This is a piece of code from my project. Enum is global (client / server) I have cut out a fragment for an example.
|