Mad Gunther
Apprentice
Posts: 45
Likes Given: 11
Likes Received: 5 in 5 posts
Joined: Oct 2015
Reputation: 1
|
RE: Sphere 56c/d Unlimited Speed
Have you tried out @UserExWalkLimit?
You just need to put the values on walkbuffer and walkregen, you can find them out in sphere.ini
// Walk limiting code: buffer size (in tenths of second)
WalkBuffer=75
// Walk limiting code: regen speed (%)
WalkRegen=25
then you can just use the trigger this way:
Code:
[events e_antispeedhack]
ON=@UserExWalkLimit
src.jail
src.sysmessage=You have been jailed for using speed hack!
or do checkouts for lag spikes like this one, but seems like your shard runs flawless without it...
Code:
[events e_antispeedhack]
ON=@UserExWalkLimit
if !(<src.findid.i_antispeedhackmemory>)
serv.newitem=i_antispeedhackmemory
new.equip <src>
new.timerd={0.5 1.3 2.5 3.7 } //random values to trick players, that goes along with the values posted above (walkregen and walkbuffer)
return 1
else
src.jail
src.sysmessage=You have been jailed for using speed hack!
endif
////////////////////////////////////////////////////////////
[itemdef i_antispeedhackmemory]
ID=i_memory
TYPE=t_eq_script
NAME=antispeedhack memory
ON=@Timer
remove
return 1
Something moreless like that should work, it is just try and fail and then try again until it work the way you want it, nothing that you don´t know already for sure... I have to script this yet for my shard too, so i hope it helps!
Un saludo y suerte!
(This post was last modified: 06-18-2016 09:08 AM by Mad Gunther.)
|
|
06-18-2016 09:02 AM |
|
|
Criminal
Journeyman
Posts: 182
Likes Given: 38
Likes Received: 22 in 22 posts
Joined: Jun 2015
Reputation: 0
SantiagoUO.com
|
|
06-18-2016 09:52 AM |
|
|
Mad Gunther
Apprentice
Posts: 45
Likes Given: 11
Likes Received: 5 in 5 posts
Joined: Oct 2015
Reputation: 1
|
RE: Sphere 56c/d Unlimited Speed
That´s really odd, in source everything looks ok:
bool CClient::Event_CheckWalkBuffer()
{
ADDTOCALLSTACK("CClient::Event_CheckWalkBuffer");
// Check if the client is trying to walk too fast.
// Direction changes don't count.
if ( !g_Cfg.m_iWalkBuffer )
return true;
if ( (m_iWalkStepCount % 7) != 0 ) // only check when we have taken 8 steps
return true;
// Client only allows 4 steps of walk ahead.
LONGLONG CurrTime = static_cast<LONGLONG>(GetTickCount());
int iTimeDiff = static_cast<int>((CurrTime - m_timeWalkStep) / 10);
int iTimeMin = m_pChar->IsStatFlag(STATF_OnHorse|STATF_Hovering) ? 70 : 140; // minimum time to move 8 steps
if ( m_pChar->m_pPlayer && m_pChar->m_pPlayer->m_speedMode != 0 )
{
// Speed Modes:
// 0 = Foot=Normal, Mount=Normal 140 - 70
// 1 = Foot=Double Speed, Mount=Normal 70 - 70 = 70
// 2 = Foot=Always Walk, Mount=Always Walk (Half Speed) 280 - 140 = x2
// 3 = Foot=Always Run, Mount=Always Walk 140 - 140 = 70|x2 (1|2)
// 4 = No Movement N/A - N/A = (handled by OnFreezeCheck)
if ( m_pChar->m_pPlayer->m_speedMode & 0x01 )
iTimeMin = 70;
if ( m_pChar->m_pPlayer->m_speedMode & 0x02 )
iTimeMin *= 2;
}
if ( iTimeDiff > iTimeMin )
{
int iRegen = ((iTimeDiff - iTimeMin) * g_Cfg.m_iWalkRegen) / 150;
if ( iRegen > g_Cfg.m_iWalkBuffer )
iRegen = g_Cfg.m_iWalkBuffer;
else if ( iRegen < -((g_Cfg.m_iWalkBuffer * g_Cfg.m_iWalkRegen) / 100) )
iRegen = -((g_Cfg.m_iWalkBuffer * g_Cfg.m_iWalkRegen) / 100);
iTimeDiff = iTimeMin + iRegen;
}
m_iWalkTimeAvg += iTimeDiff;
int oldAvg = m_iWalkTimeAvg;
m_iWalkTimeAvg -= iTimeMin;
if ( m_iWalkTimeAvg > g_Cfg.m_iWalkBuffer )
m_iWalkTimeAvg = g_Cfg.m_iWalkBuffer;
else if ( m_iWalkTimeAvg < -g_Cfg.m_iWalkBuffer )
m_iWalkTimeAvg = -g_Cfg.m_iWalkBuffer;
if ( IsPriv(PRIV_DETAIL) && IsPriv(PRIV_DEBUG) )
SysMessagef("Walkcheck trace: %i / %i (%i) :: %i", iTimeDiff, iTimeMin, oldAvg, m_iWalkTimeAvg);
if ( m_iWalkTimeAvg < 0 && iTimeDiff >= 0 ) // TICK_PER_SEC
{
// Walking too fast.
DEBUG_WARN(("%s (%lx): Fast Walk ?\n", GetName(), GetSocketID()));
if ( IsTrigUsed(TRIGGER_USEREXWALKLIMIT) )
{
if ( m_pChar->OnTrigger(CTRIG_UserExWalkLimit, m_pChar) != TRIGRET_RET_TRUE )
return false;
}
}
m_timeWalkStep = CurrTime;
return true;
}
bool CClient::Event_Walk( BYTE rawdir, BYTE sequence ) // Player moves
{
ADDTOCALLSTACK("CClient::Event_Walk");
// The client is sending a walk request to server, so the server must check
// if the movement is possible and reply with another allow/reject packet
// Return:
// true = walking was allowed
// false = walking was rejected
// The theory....
// The client sometimes echos 1 or 2 zeros or invalid echos when you first start
// walking (the invalid non zeros happen when you log off and don't exit the
// client.exe all the way and then log back in, XXX doesn't clear the stack)
if ( !m_pChar )
return false;
DIR_TYPE dir = static_cast<DIR_TYPE>(rawdir & 0x0F);
if ( dir >= DIR_QTY )
{
new PacketMovementRej(this, sequence);
return false;
}
CPointMap pt = m_pChar->GetTopPoint();
CPointMap ptOld = pt;
if ( dir == m_pChar->m_dirFace )
{
if ( IsSetEF(EF_FastWalkPrevention) )
{
// The fastest way to get system clock is using g_World.GetCurrentTime().GetTimeRaw() to
// read the value already stored by Sphere main timer. But this value is only updated at
// tenths of second precision, which won't work here because we need milliseconds precision.
// So to get this precision we must get the system clock manually at each walk request.
INT64 iCurTime = CWorldClock::GetSystemClock();
if ( iCurTime < m_timeNextEventWalk ) // fastwalk detected
{
new PacketMovementRej(this, sequence);
return false;
}
INT64 iDelay = 0;
if ( m_pChar->IsStatFlag(STATF_OnHorse|STATF_Hovering) )
iDelay = (rawdir & 0x80) ? 70 : 170; // 100ms : 200ms
else
iDelay = (rawdir & 0x80) ? 170 : 370; // 200ms : 400ms
m_timeNextEventWalk = iCurTime + iDelay;
}
else if ( !Event_CheckWalkBuffer() )
{
new PacketMovementRej(this, sequence);
return false;
}
// Move in this dir.
pt.Move(dir);
// Check the z height here.
// The client already knows this but doesn't tell us.
if ( m_pChar->CanMoveWalkTo(pt, true, false, dir) == NULL )
{
new PacketMovementRej(this, sequence);
return false;
}
if ( !m_pChar->MoveToChar(pt) )
{
new PacketMovementRej(this, sequence);
return false;
}
// Check if I stepped on any item/teleport
TRIGRET_TYPE iRet = m_pChar->CheckLocation(false);
if ( iRet == TRIGRET_RET_FALSE )
{
m_pChar->SetUnkPoint(ptOld); // we already moved, so move back to previous location
new PacketMovementRej(this, sequence);
return false;
}
// Are we invis ?
m_pChar->CheckRevealOnMove();
// Set running flag if I'm running
m_pChar->StatFlag_Mod(STATF_Fly, (rawdir & 0x80) ? true : false);
if ( iRet == TRIGRET_RET_TRUE )
{
new PacketMovementAck(this, sequence);
m_pChar->UpdateMove(ptOld, this); // Who now sees me ?
addPlayerSee(ptOld); // What new stuff do I now see ?
}
m_timeLastEventWalk = CServTime::GetCurrentTime();
m_iWalkStepCount++; // Increase step count to use on walk buffer checks
}
else
{
// Just a change in dir.
new PacketMovementAck(this, sequence);
m_pChar->m_dirFace = dir;
m_pChar->UpdateMove(ptOld, this); // Who now sees me ?
}
return true;
}
The only thing that comes to my mind is try to replicate the code on source with your own script using <serv.time> and find some way to count the tiles, wich i don´t know really how to handle it. But i don´t know why it doesn´t work when it should.
(This post was last modified: 06-18-2016 11:59 PM by Mad Gunther.)
|
|
06-18-2016 10:39 AM |
|
|