Fastwalk system
Moderator: POL Developer
Fastwalk system
RunUO uses client/server fastwalk system to prevent use of gear, in fact, if a client uses some speedup software to increase its speed, even if the client sees its player run faster than normal, the server put the player at the right position. (more tiles backward).
This is a very important feature and it would be very nice to be implemented...
This is a very important feature and it would be very nice to be implemented...
Last edited by VeNdOr on Sun Nov 05, 2006 9:53 am, edited 1 time in total.
-
- Adept Poster
- Posts: 85
- Joined: Wed Aug 30, 2006 5:24 pm
- Location: Italy
I agree strongly with one thing: That this be optional. Some shards simply have zero trouble with this sort of thing, and it would be nice to leave out what I suspect could be a fairly significant amount of processing.
That said... this is a very interesting issue that I wish I knew more about the specifics of the walk-related packets and client/server communications to play with, as an exercise. I imagine it would ultimately have to come down to being able to keep a running total of incoming walk request packets and being able to determine if they have been coming in at too fast a rate. The trick, I imagine, would be in finding a sweet spot where you catch enough fast walkers, but don't get anyone that simply has a very fast connection... beyond doing it in such a way so as not to slow things down generally.
That said... this is a very interesting issue that I wish I knew more about the specifics of the walk-related packets and client/server communications to play with, as an exercise. I imagine it would ultimately have to come down to being able to keep a running total of incoming walk request packets and being able to determine if they have been coming in at too fast a rate. The trick, I imagine, would be in finding a sweet spot where you catch enough fast walkers, but don't get anyone that simply has a very fast connection... beyond doing it in such a way so as not to slow things down generally.
well I've done this with a packethook with a small bit of lag attached to it. It was enough to generate many complaints about it in legitimate situations and I stopped it. The core could possibly handle this a bit faster to the point where it wont be lagging people behind a little. Marilla its not that much processing at all even in scripts. Clients are sent random 32-bit numbers that the client recieves and automatically sends back with the move request packet (which its doing anyway, just with POL its 00 00 00 00 since POL doesnt send any of these packets). POL just needs to check that its an actual number it sent and that its not 0 and it will be fine. Its still a bit rough to do in a packethook though.
That's why I said I wished I knew more about how the walk packets worked and stuff
So, how do the client/server deal with the issue of the walk requests being queued up by the client? Does the client just send 00's until it starts getting acks with the next numbers to use, or does the server pre-send something to the client to tell it which numbers to use for it's first couple of walk requests?
Then, beyond that, I'm guessing the client just stores the key values sent in the acks and sends them back out, in order, with the walk requests from there on, and then the server keeps track of the numbers it has sent the client, and validates them on the incoming walk requests to be sure it's sending back the same info it sent out?
Any chance we can see the packet hook you did? That might get some juices flowing.
So, how do the client/server deal with the issue of the walk requests being queued up by the client? Does the client just send 00's until it starts getting acks with the next numbers to use, or does the server pre-send something to the client to tell it which numbers to use for it's first couple of walk requests?
Then, beyond that, I'm guessing the client just stores the key values sent in the acks and sends them back out, in order, with the walk requests from there on, and then the server keeps track of the numbers it has sent the client, and validates them on the incoming walk requests to be sure it's sending back the same info it sent out?
Any chance we can see the packet hook you did? That might get some juices flowing.
Basically the client has this all hardcoded. You can use the 0xBF packet to send these 32-bit numbers.
http://packets.polserver.com/index.php? ... acket=0xBF
On login, you'd use 0xBF with the first subcommand which initializes the buffer for movement. You can send 6 32-bit numbers to the client. When the client requests to move with packet 0x02, appended onto the end of it is going to be either one of these 32 bit numbers or 0.
http://packets.polserver.com/index.php? ... acket=0x02
When one of these moves goes through, you evaluate this number to see if you are going to send 0x21 (denied) or 0x22 (accept) (POL automatically accepts of course so in a packethook, you'd block the initial move request and send deny to the client if needed)
http://packets.polserver.com/index.php? ... acket=0x21
http://packets.polserver.com/index.php? ... acket=0x22
Now what I had was an outside script (checking a prop on the character to see if it was going and if not, start_script for each character) that at regular intervals, would send out 0xBF with the second subcommand which sends one more key to the client for every successful move they made. So basically, this makes the client receive keys at a regular interval as its moving so it should never run out of keys unless of course, you're running too fast or you're running beyond the lag buffer (smoothwalk). But the client does help the server a lot in that situation if you decide to use it because if it ever requests a move and its out of keys to send, it just sends 0. I say though that you SHOULD check if any non-zero was actually sent to the client in case someone mods their packets to send anything other than 0 which would break the whole system if the server wasn't checking.
This was the code I used but apparently, it was a bit laggy to use..
antispeed.src
antispeedhelper.src
login.src and reconnect.src
http://packets.polserver.com/index.php? ... acket=0xBF
On login, you'd use 0xBF with the first subcommand which initializes the buffer for movement. You can send 6 32-bit numbers to the client. When the client requests to move with packet 0x02, appended onto the end of it is going to be either one of these 32 bit numbers or 0.
http://packets.polserver.com/index.php? ... acket=0x02
When one of these moves goes through, you evaluate this number to see if you are going to send 0x21 (denied) or 0x22 (accept) (POL automatically accepts of course so in a packethook, you'd block the initial move request and send deny to the client if needed)
http://packets.polserver.com/index.php? ... acket=0x21
http://packets.polserver.com/index.php? ... acket=0x22
Now what I had was an outside script (checking a prop on the character to see if it was going and if not, start_script for each character) that at regular intervals, would send out 0xBF with the second subcommand which sends one more key to the client for every successful move they made. So basically, this makes the client receive keys at a regular interval as its moving so it should never run out of keys unless of course, you're running too fast or you're running beyond the lag buffer (smoothwalk). But the client does help the server a lot in that situation if you decide to use it because if it ever requests a move and its out of keys to send, it just sends 0. I say though that you SHOULD check if any non-zero was actually sent to the client in case someone mods their packets to send anything other than 0 which would break the whole system if the server wasn't checking.
This was the code I used but apparently, it was a bit laggy to use..
antispeed.src
Code: Select all
use uo;
use os;
use polsys;
use unicode;
use util;
program AntiSpeedHack()
return 1;
endprogram
exported function HandleSpeedHackers(character, byref packet)
var direction := packet.GetInt8(1);
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 packet := CreatePacket(0xBF, 9);
packet.SetInt16(1,0x0009);
packet.SetInt16(3,0x0002);
packet.SetInt32(5,newkey);
packet.SendPacket(character);
return 0;
endif
var shackcheck := packet.GetInt32(3);
var sstack := GetObjProperty(character, "#shackstack");
var moves := CInt(GetObjProperty(character, "#moves"));
if(shackcheck && shackcheck in sstack && 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
Code: Select all
use uo;
use os;
use polsys;
use file;
use util;
var packet, newkey, shackwarning;
program antispeed(who)
SetObjProperty(who, "#movepid", GetPid());
while(GetObjProperty(who, "#moves"))
if (GetEquipmentByLayer(who, 25))
sleepms(80);
else
sleepms(160);
endif
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)
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
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);
Last edited by CWO on Wed Nov 08, 2006 1:20 am, edited 1 time in total.
-
- Distro Developer
- Posts: 2825
- Joined: Thu Feb 02, 2006 1:41 pm
- Location: San Antonio, Texas
- Contact:
I agree with Marilla, it should be an option in serverspecopt. I was personally accused of using FastWalk on a shard. This was back in my early UO days and had no idea what Fast Walk was. In truth I had a Broadband connection and the other user (the plaintif) was on a dial-up. So it appeared to them that I was "fastwalking" when in reality I wasn't.
who uses the horrible client 3d? however i don't want the notification of whoes uses fastwalk program, i want only that server forces clients to go at the same max velocity as runuo doesCWO wrote:It appeared to him. But what players see and what the server sees are 2 different things. Theres only one problem so far seen and thats with the 3D client. It really does run slightly faster than the 2D client.
and thats what the scripts I posted above do... it sends the reject packet before saying "Too Fast!" in antispeed.src. Then after that, it blocks the move packet from POL. This is exactly how you force them back to their old spot if they stepped to quickly. But just like we said, it would probably fare better in the core since the scripts tend to generate a bit of lag.
And on my reply, I was saying, if you're on broadband, you would appear to be moving faster to him because hes not only lagging in running but lagging in seeing where you are. So you suddenly jump to him. But the server sees every step you take otherwise you wouldn't be able to take them well in the first place.
And on my reply, I was saying, if you're on broadband, you would appear to be moving faster to him because hes not only lagging in running but lagging in seeing where you are. So you suddenly jump to him. But the server sees every step you take otherwise you wouldn't be able to take them well in the first place.
Remember this, this script is triggered 10 times/sec on a mount 5 times/sec without a mount when someone moves. This script also runs critical too. 20 people online can trigger this 200 times. On top of that, this can reach 100 or so instructions per invocation easily... multiply it all up and you have around 20000 instructions per second 1.2 million per minute... way overloading for critical.CWO wrote: But just like we said, it would probably fare better in the core since the scripts tend to generate a bit of lag.
- Core Essence
- Neophyte Poster
- Posts: 38
- Joined: Tue Feb 07, 2006 10:40 am
- Location: Palermo, Italy
News... as in... you want a status report from the Devs as to whether or not they have hopping straight into line to get on what you want them doing?
I think the lack of any Dev posting in this thread could be indicative of something - though perhaps not of outright rejection of the idea. Perhaps they have long since been considering how to best do such a thing, but because they know how much potential for trouble there could be with this, they are opting to carefully consider it, among all the other requests and plans they have, and so right now, they just aren't able to comment much more on it.
So.... be patient. They know this is something that people want, as are so many other things.
I think the lack of any Dev posting in this thread could be indicative of something - though perhaps not of outright rejection of the idea. Perhaps they have long since been considering how to best do such a thing, but because they know how much potential for trouble there could be with this, they are opting to carefully consider it, among all the other requests and plans they have, and so right now, they just aren't able to comment much more on it.
So.... be patient. They know this is something that people want, as are so many other things.
-
- Former Developer
- Posts: 308
- Joined: Mon Jan 30, 2006 9:28 am
- Location: Germany, Bavaria
- Contact:
one of these "other things" is to decide to read YOUR huge postings or to not read'em. THIS posting I'm replying to is a very short post, so I read'em. but in most cases I don't have time to read tons of lines...Marilla wrote:So.... be patient. They know this is something that people want, as are so many other things.
Shinigami
I don't write the long ones for you guys... the long ones are written for Austin's #1's, to keep them busy, and for people asking a question.Shinigami wrote:one of these "other things" is to decide to read YOUR huge postings or to not read'em. THIS posting I'm replying to is a very short post, so I read'em. but in most cases I don't have time to read tons of lines...Marilla wrote:So.... be patient. They know this is something that people want, as are so many other things.
Shinigami
For you guys, when I'm trying to make a point, I keep it short and sweet. Like this post.
But while I'm thinking about it, I should also mention... *gets yanked away from the keyboard*...
Sorry for bringing up an old post!
Would it be faster to just hook the walk packet from the client, record the time of each step, compare it against the previous time, if it's too close (too many walk packets from the client) notify a GM and/or disconnect the character or just send a deny packet?
If anyone has some "speed hack" software and a live shard, I could write a packet hook implementing the above suggestion and we could test it out. Or we could all wait until 098.
Would it be faster to just hook the walk packet from the client, record the time of each step, compare it against the previous time, if it's too close (too many walk packets from the client) notify a GM and/or disconnect the character or just send a deny packet?
If anyone has some "speed hack" software and a live shard, I could write a packet hook implementing the above suggestion and we could test it out. Or we could all wait until 098.
I already made one and posted it in this thread. The problem is, it adds a very noticeable amount of lag to the shard and it false alarms a lot. Remember this too tek, you cant expect every packet to be evenly spaced, it comes in in bursts legitimately too. My packethook uses a basically foolproof system that makes sure you have an allowance of moves over a period of time. The problem is, the lag it causes builds up and causes it to trigger the alarm.