What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal

FixIdle - Thread Safe version of the Unstucker.

fifidong

Member
Joined
May 31, 2012
Messages
124
Reaction score
0
Thank you eax for the Unstucker!
http://www.thebuddyforum.com/demonb...er-restarts-if-your-character-gets-stuck.html

This is what I wrote for myself however.
Since Threads.Sleep(...) does bad things. (DB is not thread-safe)

Feel free to complain. Like I care...


Delete or comment this line if you hate that message. I use it to see the pathing performance is on my profiles.
Code:
// Log( "Counting " + counter.ToString() );


Code:
using System;
using System.Collections.Generic;
using System.Windows;
using Zeta;
using Zeta.Common;
using Zeta.CommonBot;
using Zeta.CommonBot.Logic;
using Zeta.Common.Plugins;
using Zeta.Internals;
using Zeta.Internals.Actors;
using Zeta.Internals.Service;

namespace fifidong {
	// Inherit IPlugin
	//		Zeta.Common.Plugins
    public class FixIdle : IPlugin {
		
		// ------------------------------------------------------------
		// Configuration here
		// ------------------------------------------------------------
		private uint _TIMELIMIT = 5;	// 5 Second Countdown.
	
		// Inherited Varaibles from Zeta.Common.Plugins.IPlugin
		public string Author { get { return "fifidong"; } }
		public string Description { get { return "Check for Idle and Fix it!"; } }
		public Window DisplayWindow { get { return null; } }
		public string Name { get { return "Fix Idle Version Alpha!"; } }
		
		// Inherited Varaibles from System.IEquatable<T>
		public Version Version { get { return new Version(0,1); } }
		
		// FixIdle Plugin Local Variables
		private bool isInValidGame;
		private bool isRestarting;
		private Vector3 curPos;
		private uint counter;
		private DateTime curTime;
		
		// Debugging variables
		private bool firstDBG = false;
		
		// Commonly used functions
		private void Log( string strMsg ) { Logging.Write( string.Format("[FixIdle] {0}", strMsg ) ); }
		
		// Functions
		public void OnDisabled() { Log( "Disabling the Plugin" ); }
		public void OnEnabled() { Log( "Enabling the Plugin" ); }
		
		// Initialize the Plugin Local Variables
		public void OnInitialize() {
			Log( "Initializing the Plugin" );
			isInValidGame = false;
			isRestarting = false;
			counter = 0;
			curTime = DateTime.Now;
			curPos = ZetaDia.Me.Position;
		}
		
		public void RemoveAllBehavior() {
			ProfileManager.CurrentProfileBehavior.ResetCachedDone();
		}
		
		// Do as little as possible here!
		public void OnPulse() {
		
			// Cond: Am I in aValid Game?
			if( ZetaDia.IsInGame && ZetaDia.Me.IsValid ) {
				
				// Cond: Am I in a town?
				if( !ZetaDia.Me.IsInTown && !isRestarting ) {
					if(  (DateTime.Now.Second != curTime.Second) ) { // Count every one second
						
						// Cond: Position is same and Not in combat!
						if( curPos == ZetaDia.Me.Position ) {
							// Log( "Counting " + counter.ToString() );
							bool isReadyToPort = (counter++ >= _TIMELIMIT);
							// Only when Position is same and Not in Combat... Do something.
							if( isReadyToPort ) {
							
								Log( "Using Town Portal" );
								
								// Now time has elapsed.  OH NOEZ.
								RemoveAllBehavior();
								ZetaDia.Me.UseTownPortal();
								isRestarting = true;
							}
							
						} else counter = 0;
						
						
						// And update the time variable
						curTime = DateTime.Now;
						curPos = ZetaDia.Me.Position;
						
					}
					
				// Cond: Did I invoke Restart and finally got to the Town?	
				} else if( ZetaDia.Me.IsInTown && isRestarting ) {
					
					// Leave the game and reset the flag
					ZetaDia.Service.Games.LeaveGame();
					isRestarting = false;
				}
			}
		}
		public void OnShutdown() {}
		public bool Equals( IPlugin inPlug ) {	
			return ( (inPlug.Name == Name) && (inPlug.Version == Version) && (inPlug.Author == Author) );
		}
		
    }
}
 

Attachments

Last edited:
Since Threads.Sleep(...) does bad things. (DB is not thread-safe)


i am clueless of what you mean with that - care to elaborate for all those non-profile-writers like myself?
 
Since Threads.Sleep(...) does bad things. (DB is not thread-safe)


i am clueless of what you mean with that - care to elaborate for all those non-profile-writers like myself?

Something to do with Concurrency Programming? Resource-Starvation/Lockout?
 
fifidong got fancy!

Although, very good job.
The structure of the pulse code is fine, but why is everything else so messy? ;)



confuse me even more please :|
What he means is, Demonbuddy only uses one thread, and this thread passes through plugins.

If we take that, and do a Thread.Sleep() then Demonbuddy is no longer working while that Thread.Sleep() is active.


This can cause MASSIVE issues even on short sleeps, hence the new plugin by fifi.
 
DemonBuddy is not using Multi-Threading (it's a programming concept, to execute multiple processes at the same time). Multi-threading is generally used to get better process execution performance. As DB seems not to use multi-threading, the use of the Threads.sleep function which is written for multi-threading can do "bad things". I let Fifidong give more details on this ;).
 
thanks for explaining guys - i will use this plugin right away
 
Sitting here watching the plugin do nothing for the last 5 minutes that two of my bots have been stuck. Perhaps I did something wrong. Shows up in the plugins manager via DB window and I do have it checked (enabled).
 
Warning: Do not use the plugin. It will go into an infinite loop casting TP when your inventory is full.
 
Is it casting the loop in town? cause you cannot TP in town do you have yellows?
 
Good job.

But that whole thread safety bit...it simply means that you shouldn't call the API from a new thread, because by doing so you might interrupt another thread which could screw a lot of things up. Thread.Sleep was an acceptable solution since there was no notification system (that I saw) available. So Unstucker is thread safe.

no1knowsy said:
What he means is, Demonbuddy only uses one thread, and this thread passes through plugins.

If we take that, and do a Thread.Sleep() then Demonbuddy is no longer working while that Thread.Sleep() is active.


This can cause MASSIVE issues even on short sleeps, hence the new plugin by fifi.

This is probably true. Blocking in OnPulse() probably isn't the best practice, but if Unstucker doesn't somehow pause while waiting for the player to leave game, bad things seem to happen.
 
Last edited:
Good job.

But that whole thread safety bit...it simply means that you shouldn't call the API from a new thread, because by doing so you might interrupt another thread which could screw a lot of things up. Thread.Sleep was an acceptable solution since there was no notification system (that I saw) available. So Unstucker is thread safe.



This is probably true. Blocking in OnPulse() probably isn't the best practice, but if Unstucker doesn't somehow pause while waiting for the player to leave game, bad things seem to happen.

I was trying to find you yesterday eax on IRC channel.
So you can put that into yours. Since your code is what most people use.
Can you update your Unstucker, so we dont have two duplicates threads on unstucker?

And I'll just make this link to yours.
 
in the IRC from the DemonBuddy Dev.

Did you read my post?

I was trying to find you yesterday eax on IRC channel.
So you can put that into yours. Since your code is what most people use.
Can you update your Unstucker, so we dont have two duplicates threads on unstucker?

And I'll just make this link to yours.

Put what into mine?
 
Hmm - it didn't work for me. I just got back to my char which had been idling for over an hour.
Code:
[18:45:39.924 N] [Belphegor] Health is low, using health potion
[20:09:56.574 N] [FixIdle] Disabling the Plugin
Look at the time stamps. I'm doing core of arreat, and I disabled the plugin when I came back. It should've completed a few runs in between those 2 lines :P
 
Warning: Do not use the plugin. It will go into an infinite loop casting TP when your inventory is full.

You probably had yellows in your bag. When you identify an item, it has similar animation + casting bar as if you are porting to town. Try TPing in town by yourself... you can't.
 
Muchas Gracias!

Had a stash idle. And idle at start point, last log msg "[01:11:29.866 N] [FixIdle] Using Town Portal"


Does Fix idel change the combat position? Cause my DH gets to close to Sakoth now.
 
Last edited:
thread safety comes into play if you are trying to multithread something that is not thread safe. db runs the entire bot in a single thread therefore thread safety is not a concern, unless you try to spawn a new thread or kill the existing one from a plugin. good thought though. calling a thread.sleep is not an issue as when the bot is 'stuck' it isn't doing anything useful anyway. it's the same as pausing the bot.
 
Back
Top