Timers are fine but I always cringe a bit when I hear them mentioned for a few reasons...
#1: timers as you are suggesting are PER client. This means each delayed action is a new timer for each person online... Timers aren't exactly inefficient by any means but the way you use them certainly can be.
#2: Disposal! What happens when the client disconnects, the timer elapses and tries to perform actions on something which is disposed or disconnected (IE: Sending stamina update packet to client). There's obviously ways around this and the issue comes up in any threading method but PLEASE be careful of it cause it's an annoying problem to try to debug sometimes.
#3: Related to point one but using a thread or a timer to control some extremely small, simple task such as boosting a value can run into inefficiencies when you start doing it too often... think through things (can I combine this with an existing thread/timer without losing efficiency?!)
I've tried a few methods to go about it and I don't see any of them as being the 'best' but they are options to think about.
1: Global thread which boosts ALL users stamina (can be combined with other threads... generally done in combination with boosting users XP bar). In this model you have a single thread which runs through all users connected, checks the time since last stamina gain (or xp gain), checks their conditions (sitting/laying or not) and then performs an action.
I like this option as it's not taking up many resources. A single thread doing all the work. The issue is if the thread dies for some reason (you coded it wrong for example) then no one on the server can gain stamina till you fix it usually by restarting the server.
2: Use a timer/thread per client.
I dislike this a little bit because of the increased (needless imo) cost of processing it for each user. It's small but lets say we start doing a stamina timer per client, xp timer per client, online training timer per client, auto attack timer per client.... etcetcetc.
How many timers do we really want running at once? Sooner or later that will impact our performance.
Ooh and as for actual code... i'd use something like...
var toUp = 1;
if(user.Action == ActionType.Sit || user.Action == ActionType.Lay)
if(DateTime.Now > user.SatAt.AddMilliseconds(200))//This is when they perform the sit action itself. Stops them from gaining stamina by holding sit key while jumping.
toUp = 6;
user.Stamina = Math.Min(user.Stamina + toUp, user.MaxStamina);
How does that even remotely make any sense to you...
Seriously....
Maybe he likes to have negative values rofl. However it's most likely a byte, which means it's unsigned, so it cannot have negative values, where signed bytes (sbyte) can have a negative value.
But in the end I don't think he knows what the operators mean.
Timers are fine but I always cringe a bit when I hear them mentioned for a few reasons...
#1: timers as you are suggesting are PER client. This means each delayed action is a new timer for each person online... Timers aren't exactly inefficient by any means but the way you use them certainly can be.
#2: Disposal! What happens when the client disconnects, the timer elapses and tries to perform actions on something which is disposed or disconnected (IE: Sending stamina update packet to client). There's obviously ways around this and the issue comes up in any threading method but PLEASE be careful of it cause it's an annoying problem to try to debug sometimes.
#3: Related to point one but using a thread or a timer to control some extremely small, simple task such as boosting a value can run into inefficiencies when you start doing it too often... think through things (can I combine this with an existing thread/timer without losing efficiency?!)
I've tried a few methods to go about it and I don't see any of them as being the 'best' but they are options to think about.
1: Global thread which boosts ALL users stamina (can be combined with other threads... generally done in combination with boosting users XP bar). In this model you have a single thread which runs through all users connected, checks the time since last stamina gain (or xp gain), checks their conditions (sitting/laying or not) and then performs an action.
I like this option as it's not taking up many resources. A single thread doing all the work. The issue is if the thread dies for some reason (you coded it wrong for example) then no one on the server can gain stamina till you fix it usually by restarting the server.
2: Use a timer/thread per client.
I dislike this a little bit because of the increased (needless imo) cost of processing it for each user. It's small but lets say we start doing a stamina timer per client, xp timer per client, online training timer per client, auto attack timer per client.... etcetcetc.
How many timers do we really want running at once? Sooner or later that will impact our performance.
Ooh and as for actual code... i'd use something like...
var toUp = 1;
if(user.Action == ActionType.Sit || user.Action == ActionType.Lay)
if(DateTime.Now > user.SatAt.AddMilliseconds(200))//This is when they perform the sit action itself. Stops them from gaining stamina by holding sit key while jumping.
toUp = 6;
user.Stamina = Math.Min(user.Stamina + toUp, user.MaxStamina);
or you can have one Timer per player and that timer handles everything like (stamina/xpbar/flash name etc etc) << thats how am doing it , and when that Player disconnect the Function Dispose .
@pro4never
1 timer that goes over all clients and check for times and update them. But that would make delays for players. More clients, bigger gap ( if Im not wrong)
tho thread sounds more suitable for this (if coded right).
@pro4never
1 timer that goes over all clients and check for times and update them. But that would make delays for players. More clients, bigger gap ( if Im not wrong)
tho thread sounds more suitable for this (if coded right).
There's no real difference between timers and threads when it comes to purpose...
They both deal with delayed or timed actions.
Threads obviously server a better use in most 'constant' actions where threads are more often used in something that only happens periodically (many exceptions but that's how I think of it)
As for actual execution time though... when a timer executes its code it's running on a separate thread so there's no real differences there.
The only way you could 'load balance' the code would be to determine how long the code inside took to run and reduce the loop time by that amount.
EXAMPLE:
Code:
while (true)
{
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
//RUN YOUR CODE
sw.Stop();
Thread.Sleep((int)Math.Max(10, 100 - sw.ElapsedMilliseconds));
}
Obviously a rather trash example but what I'm saying is that if you have a thread which for some odd reason takes you.... 50 ms to process all of (seems a large amount of processing per thread loop imo... but to each his own!) then you reduce the final thread sleep by 50.
I suggest the Math.Max simply because what happens if you want the thread to run every 100 ms but this loop it fucks up and takes 500 ms to process... you could end up with a negative number and I have no idea what a negative number would do to a thread.sleep.
[Release-CT] SP Refill 08/03/2011 - S4 League Hacks, Bots, Cheats & Exploits - 24 Replies Hi community,
I want release SP Instant Refill like old patches.
The refill of SP isn't slow but instantaneous
[Question/Request]Make PM/GM Unlimited Stamina 06/21/2011 - CO2 Private Server - 2 Replies This is my current Stamina coding in character.cs:
#region Stamina
if (Time32.Now > client.Entity.StaminaStamp.AddMilliseconds(500))
{
if (client.Entity.Action == Game.Enums.ConquerAction.Sit)
{
if (!client.Entity._Status.ContainsBitValue((int)Game .Enums.StatusFlag.Fly))
{
WTS Necklance of fortune (Stamina 3) + Flying Ring (Stamina 3) Cyprius 04/02/2009 - Archlord Trading - 0 Replies Hi all,
WTS Necklance of fortune (Stamina 3) + Flying Ring (Stamina 3)
Each one 20€, i accept only paypal and €,
if someone interesetet pm me thanks!
The items are on Cyprius!