Fastwalk system
Actually we found, as common as loading up a 3D client. This was a problem for a while on my shard too... now I have a different solution but requires a lot of staff monitoring. I have the move packet hooked to only count up a prop #moves if they move. Then I have a script run once per second on everyone online taking that prop, subtract 5 or 10 from it (5 if on foot, 10 if on mount) and add it to an array prop. Then clear that #moves prop. My staff have a command that will bring up a list in an HTML gump with every result from the last 5 minutes (in 5 second intervals) of everyone online. The +'s (moving faster than normal) in red text, the others in black. We easily spot who is speedhacking this way. But this is the same old monitor move instead of prevention which would be great to be able to do.
Don’t you have problems with 3D clients?
Our test shows that 3D client run 5-10% faster then 2D clients. More and more players are beginning to use 3D, because 2D client above 3.X will lag if the latency between the server clients is 140+ ping. 3D does not lag for the same player, so 3D is the only choose if someone want to play on a server located on another continent (EU Vs. US).
The fact that 3D are faster then 2D, are a huge problem in PvP for obvious reasons, and we currently have no way of even out that advantage.
The only solution I can see to this problem is to hope that a core fastwalk prevention system will also limit the 3D client to the same speed as a 2D client.
Our test shows that 3D client run 5-10% faster then 2D clients. More and more players are beginning to use 3D, because 2D client above 3.X will lag if the latency between the server clients is 140+ ping. 3D does not lag for the same player, so 3D is the only choose if someone want to play on a server located on another continent (EU Vs. US).
The fact that 3D are faster then 2D, are a huge problem in PvP for obvious reasons, and we currently have no way of even out that advantage.
The only solution I can see to this problem is to hope that a core fastwalk prevention system will also limit the 3D client to the same speed as a 2D client.
I have an idea. Write some external anti cheat program which would look for malicious tools inside ultima online folder. Without this tool connecting to shard wouldn't be possible. It can be done with aux scripts i think because i know one shard which is using such "gate" to verify player if they have that tool running or not.
This is becoming a bigger and bigger problem on our shard, so I’m desperate searching for options.
The biggest problem is not speedhack, but that 3D clients run faster then 2D client, making PvP in 3D the only option if you want to stand a chance.
Why don’t you just disconnect all clients using 3D you might ask? Because all 4.0+ 2D clients lag if you latency is 125+, but 3D clients does not have this flaw, forcing many player to play 3D.
How fast was the server you (CWO) tried that script solution on?
The biggest problem is not speedhack, but that 3D clients run faster then 2D client, making PvP in 3D the only option if you want to stand a chance.
Why don’t you just disconnect all clients using 3D you might ask? Because all 4.0+ 2D clients lag if you latency is 125+, but 3D clients does not have this flaw, forcing many player to play 3D.
How fast was the server you (CWO) tried that script solution on?
Code: Select all
use uo;
use os;
program clientchecker(who)
sleep(10);
if(who.clientversion["3D"] || who.clientversion ["Dawn"] || who.clientversion ["TD"])
SendSysMessage(who, "Sorry 3D is not supported on this server. Please log in with a 2D client.");
Sleep(3);
DisconnectClient(who);
return;
endif
endprogram
Theres no other known way to me right now.
If I find someone running constantly faster on my server or using 3D past this script, they're considered cheating.
My server is located in Denmark, and most/all players from the US, Canada etc have at least 125 ms latency/ping, meaning they will with newer 2D clients, so they have no other choose then to use 3D.Repsak wrote:Why don’t you just disconnect all clients using 3D you might ask? Because all 4.0+ 2D clients lag if you latency is 125+, but 3D clients does not have this flaw, forcing many player to play 3D.
just for the record of how this thing might work:
You wouldn't send "denywalk" packets to clients that are too fast, you would only "postpone" the sending of the "walk ok" packets (along with postponing of the actual movement and broadcasting the new position to other clients etc.)
The problem with the deny packet is following - Sometimes the client does a little "lag" between steps all by itself... The result is that instead of 3 walkrequest packets being sent with two equal pauses, it will be one "big" pause followed by the two other packets immediately one after another, even when the player is not speedhacking at all.
The solution is to have a "buffer" that stores the time of say last 3 steps, so that the speed checking system won't interfere with clients that have "in average" proper speed, only their connection/computer is a little jumpy.
Also never deny movement based on speed, simply maintain a queue of the incoming walk requests, and don't process them before they should be processed. That way you don't even need the "fastwalk prevention" that is built-in into the UO network protocol (i.e. the 0xBF subcommands, etc.) - those are actually useless.
Not sure about how this is or isn't possible in scripts, but if properly coded (into core), it shouldn't be CPU intensive at all. Just one little queue of walkrequest packets (which would be empty most of the time) and a speedmeter of last 3 steps...
You wouldn't send "denywalk" packets to clients that are too fast, you would only "postpone" the sending of the "walk ok" packets (along with postponing of the actual movement and broadcasting the new position to other clients etc.)
The problem with the deny packet is following - Sometimes the client does a little "lag" between steps all by itself... The result is that instead of 3 walkrequest packets being sent with two equal pauses, it will be one "big" pause followed by the two other packets immediately one after another, even when the player is not speedhacking at all.
The solution is to have a "buffer" that stores the time of say last 3 steps, so that the speed checking system won't interfere with clients that have "in average" proper speed, only their connection/computer is a little jumpy.
Also never deny movement based on speed, simply maintain a queue of the incoming walk requests, and don't process them before they should be processed. That way you don't even need the "fastwalk prevention" that is built-in into the UO network protocol (i.e. the 0xBF subcommands, etc.) - those are actually useless.
Not sure about how this is or isn't possible in scripts, but if properly coded (into core), it shouldn't be CPU intensive at all. Just one little queue of walkrequest packets (which would be empty most of the time) and a speedmeter of last 3 steps...
tartaros, my packethook (the one that lags too much to use) kinda handles that. Theres a "fastwalk stack" built into the client. The script sends random 32-bit Integers to the client that the client sends back in the walk packet. Initially I sent 6 of them to the client then more at regular intervals based on if you were on a mount or not. Then the hook checks the integer when it comes in with the walk packet and if it passes, will allow the packet to pass to the core. If not, the deny packet is sent back and the walk request is blocked from the core.
-
mr bubbles
- Grandmaster Poster
- Posts: 120
- Joined: Thu Jan 18, 2007 2:34 am
Based on your script, I have adjusted the system a bit, but my testing proved the system inadequate.CWO wrote:tartaros, my packethook (the one that lags too much to use) kinda handles that. Theres a "fastwalk stack" built into the client. The script sends random 32-bit Integers to the client that the client sends back in the walk packet. Initially I sent 6 of them to the client then more at regular intervals based on if you were on a mount or not. Then the hook checks the integer when it comes in with the walk packet and if it passes, will allow the packet to pass to the core. If not, the deny packet is sent back and the walk request is blocked from the core.
Take the 3D client, that send the walk packets about 5% faster then the 2D client.
1. The first walk packet is send and the server returns a "walk ok" packet, hence client can move.
2. The second packet is send, but 5% to fast, so the server will deny it and the client is forced back to the original location.
3. The third walk packet is send and accepted by the server.
So basically every other walk packet for 3D will be denied, creating a very bouncy movement experience. To solve this problem I tried to raise the timer, allowed more walk packet to be accepted, but it only improved the solution, it didn't solve it.
Tartaros suggestion, to postpone the handling of the walk packets might work, but it all depends on how the client will react to these delayed packets.
Are you sending the initialization at login/reconnect? And yes, it will cause bouncy movement because its moving partially too fast. You'll never force the client to slow down unless you actually bounce them back a bit. What you're talking about is smoothing it out which would have to be a modified on the client.
I have tested the system I described with GodClient - it's walking speed is about twice the speed of normal clients... The only little problem with it is that the first few steps are faster (which would be the same in case of sending 6 hashes in advance) , then it is forced to slow down, but since I don't deny the walkrequests, the result is that the movement is still pretty smooth.
Don't ask for scripts tho as I don't use POL (it's my own emulator)...
Don't ask for scripts tho as I don't use POL (it's my own emulator)...
if you dont send the deny then how are you slowing the movement or are you just logging it? The scripts I put up are designed to stop the movement from going too fast period. If you don't send either the accept or deny packets, either you'll hang up the client making it think its lagging or the client and server go out of sync.
Yep.CWO wrote:Are you sending the initialization at login/reconnect?
Here is my modified packet, but it can only handle speekhack, not the the movement difference in the clients
Let me point out that I am not using this on a live shard, since I was not happy with the results.
uopacket.cfg
Code: Select all
Packet 0x02
{
Length 7
ReceiveFunction antispeed:HandleSpeedHackers
}
Code: Select all
Enabled 1
Name antispeedhack
Maintainer Repsak
Email repsak@pangaea-world.dk
CoreRequired 96
Version 1.0
Author/Basis CWO
Code: Select all
use uo;
use polsys;
use util;
program Login_AntiSpeedHack(who)
SetObjProperty(who, "#moves", CInt(0));
SetObjProperty(who, "#shackwarning", CInt(0));
EraseObjProperty(who, "#movepid");
var shackstack := array;
shackstack[1] := RandomInt(0x4000000000000)+1;
shackstack[2] := RandomInt(0x4000000000000)+1;
shackstack[3] := RandomInt(0x4000000000000)+1;
shackstack[4] := RandomInt(0x4000000000000)+1;
shackstack[5] := RandomInt(0x4000000000000)+1;
shackstack[6] := RandomInt(0x4000000000000)+1;
var shstack := CreatePacket(0xBF, 29);
shstack.SetInt16(1,0x001D);
shstack.SetInt16(3,0x0001);
shstack.SetInt32(5, shackstack[1]);
shstack.SetInt32(9, shackstack[2]);
shstack.SetInt32(13, shackstack[3]);
shstack.SetInt32(17, shackstack[4]);
shstack.SetInt32(21, shackstack[5]);
shstack.SetInt32(25, shackstack[6]);
shstack.SendPacket(who);
SetObjProperty(who, "#shackstack", shackstack);
endprogram
Code: Select all
use uo;
use polsys;
use util;
program Reconnect_AntiSpeedHack(who)
SetObjProperty(who, "#moves", CInt(0));
SetObjProperty(who, "#shackwarning", CInt(0));
EraseObjProperty(who, "#movepid");
var shackstack := array;
shackstack[1] := RandomInt(0x4000000000000)+1;
shackstack[2] := RandomInt(0x4000000000000)+1;
shackstack[3] := RandomInt(0x4000000000000)+1;
shackstack[4] := RandomInt(0x4000000000000)+1;
shackstack[5] := RandomInt(0x4000000000000)+1;
shackstack[6] := RandomInt(0x4000000000000)+1;
var shstack := CreatePacket(0xBF, 29);
shstack.SetInt16(1,0x001D);
shstack.SetInt16(3,0x0001);
shstack.SetInt32(5, shackstack[1]);
shstack.SetInt32(9, shackstack[2]);
shstack.SetInt32(13, shackstack[3]);
shstack.SetInt32(17, shackstack[4]);
shstack.SetInt32(21, shackstack[5]);
shstack.SetInt32(25, shackstack[6]);
shstack.SendPacket(who);
SetObjProperty(who, "#shackstack", shackstack);
endprogram
Code: Select all
use uo;
use os;
use polsys;
use util;
program antispeed(who)
SetObjProperty(who, "#movepid", GetPid());
var packet, newkey, shackwarning;
while(GetObjProperty(who, "#moves"))
if (GetEquipmentByLayer(who, 25))
sleepms(80); // 80
else
sleepms(160); // 160
endif
set_critical(1);
newkey := RandomInt(0x4000000000000)+1;
packet := CreatePacket(0xBF, 9);
packet.SetInt16(1,0x0009);
packet.SetInt16(3,0x0002);
packet.SetInt32(5,newkey);
packet.SendPacket(who);
shackwarning := CInt(GetObjProperty(who, "#shackwarning"));
SetObjProperty(who, "#moves", CInt(GetObjProperty(who, "#moves")-1));
var shackstack := GetObjProperty(who, "#shackstack");
shackstack.append(newkey);
SetObjProperty(who, "#shackstack", shackstack);
set_critical(0);
if (shackwarning)
SetObjProperty(who, "#shackwarning", shackwarning-1);
if (shackwarning > 5)
Print(who.name + " is getting excessive speedhack warnings!");
SetObjProperty(who, "#shackwarning", CInt(0));
endif
endif
endwhile
SetObjProperty(who, "#shackwarning", CInt(0));
EraseObjProperty(who, "#movepid");
endprogram
Code: Select all
use uo;
use os;
use polsys;
use unicode;
use util;
program AntiSpeedHack()
Print("PacketHooks - Anti SpeedHack" );
return 1;
endprogram
exported function HandleSpeedHackers(character, byref packet)
var direction := packet.GetInt8(1);
var shackcheck := packet.GetInt32(3);
if ((character.facing != direction) && (character.facing != (direction - 128) ))
//Changed facing, send a new key since this isn't really a move
//var newkey := RandomInt(0x4000000000000)+1;
//var sstack := GetObjProperty(character, "#shackstack");
//sstack[6] := newkey;
//SetObjProperty(character, "#shackstack", sstack);
var packet := CreatePacket(0xBF, 9);
packet.SetInt16(1,0x0009);
packet.SetInt16(3,0x0002);
//packet.SetInt32(5,newkey);
packet.SetInt32(5, shackcheck);
packet.SendPacket(character);
return 0;
endif
var sstack := GetObjProperty(character, "#shackstack");
var moves := CInt(GetObjProperty(character, "#moves"));
if(shackcheck and shackcheck in sstack and moves < 6)
var newstack := array;
foreach num in sstack
if (num != shackcheck)
newstack.append(num);
endif
endforeach
SetObjProperty(character, "#moves", moves+1);
SetObjProperty(character, "#shackstack", newstack);
if (!GetObjProperty(character, "#movepid"))
Start_Script("antispeedhelper", character);
endif
else
SendSysMessage(character, "Too fast");
SetObjProperty(character, "#shackwarning", GetObjProperty(character, "#shackwarning")+2);
var reject := CreatePacket(0x21, 8);
reject.SetInt8(1, packet.GetInt8(2));
reject.SetInt16(2, character.x);
reject.SetInt16(4, character.y);
reject.SetInt8(6, direction);
reject.SetInt8(7, character.z);
reject.SendPacket(character);
return 1;
endif
return 0;
endfunction
I should add that the original pkg did not work, so I had to make a few modification on the original design.
My originals didn't work? Maybe I changed something since working with it last... I know when I actually last used it on my shard it would be fine until a certain number of people would log on then the shard sysload would start going up and everyone would get bogged down by that hook.
My shard has been under a total rewrite and I actually don't use that system anymore. Now I just have a counter on the script and it logs how many moves you've done while another script loops through everyone every second and logs how many moves you did against how many possible moves. My staff can see the last 5 minutes of moves to track people. At least it doesn't lag my shard anymore.
My shard has been under a total rewrite and I actually don't use that system anymore. Now I just have a counter on the script and it logs how many moves you've done while another script loops through everyone every second and logs how many moves you did against how many possible moves. My staff can see the last 5 minutes of moves to track people. At least it doesn't lag my shard anymore.
If the client works correctly (i.e. it's not modified in any way, like for example by enabling "smooth walk" in injection), it will not go more than 3 steps "in advance" from the server responses.CWO wrote:if you dont send the deny then how are you slowing the movement or are you just logging it? The scripts I put up are designed to stop the movement from going too fast period. If you don't send either the accept or deny packets, either you'll hang up the client making it think its lagging or the client and server go out of sync.
They will not go out of sync if you properly queue the too-early-incoming packets.
Thats what I was saying, the deny packet is the only way to say to the client that you can not move so you wont advance faster than you should. By not sending either, you're imitating lag which smoothwalk will override. This will just start causing problems later because the client and server aren't at the same spot. With the deny packet, you focus the client back to that spot so even with smoothwalk, you'll be forced back to that spot. This prevents severe jumping from another client's point of view. Now if someone blocks deny packets, the client will be farther forward than the server wants which would likely cause a sync error and disconnection.