GabrielShadow
Community Developer
- Joined
- Aug 17, 2015
- Messages
- 12
- Reaction score
- 0
GPS-based Land Scanner
This is a open source land scanner that will move through a GPS route from beginning to end, and for each GPS point will go to nearby houses and farms and verify if it is expiring.
How to use:
- Copy and paste the code below in the plugin editor and customize your settings on the Settings code region.
- A GPS file (db3) is needed with two points "Begin" and "End". You can customize the point names in the Settings region too.
- Go near the GPS path and hit start.
Did you like this plugin? I'm a creature that turns coffee into code. Consider buying me a cup or two of coffee
Donate with Paypal
Version 1.0:
ChangeLog:
This is a open source land scanner that will move through a GPS route from beginning to end, and for each GPS point will go to nearby houses and farms and verify if it is expiring.
How to use:
- Copy and paste the code below in the plugin editor and customize your settings on the Settings code region.
- A GPS file (db3) is needed with two points "Begin" and "End". You can customize the point names in the Settings region too.
- Go near the GPS path and hit start.
Did you like this plugin? I'm a creature that turns coffee into code. Consider buying me a cup or two of coffee

Donate with Paypal
Version 1.0:
Code:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using ArcheBuddy.Bot.Classes;
namespace Shadow.LandScanner
{
public class PluginEntry : Core
{
public static string GetPluginAuthor()
{
return "GabrielShadow";
}
public static string GetPluginVersion()
{
return "1.0.0";
}
public static string GetPluginDescription()
{
return "Shadow Land Scanner";
}
public void PluginRun()
{
#region Settings
const string gpsFilePath = @"C:\GabrielShadow\ExamplePath.db3"; // Path to your GPS file
const string gpsBeginPointName = "Begin"; // Name of the starting point in the GPS file
const string gpsEndPointName = "End"; // Name of the ending point in the GPS file
const double maxDistanceFromGpsPoint = 20; // For each GPS point, how far we are going to go to the property to get the tax info. This should be as small as possible
#endregion
this.Log(GetPluginDescription() + " started.");
try
{
const double minDistanceToUpdateTaxInfo = 4.7; // Min distance for UpdateTaxInfo is 5. However when using ComeTo method may be a bit inaccurate
Gps gps = this.ValidateAndLoadGps(gpsFilePath, gpsBeginPointName, gpsEndPointName);
gps.GpsMove(gpsBeginPointName);
List<GpsPoint> path = gps.GpsGetPath(gpsEndPointName);
path.Reverse();
List<uint> housingsScanned = new List<uint>();
List<Housing> expiringHousings = new List<Housing>();
foreach (GpsPoint gpsPoint in path)
{
this.MoveTo(gpsPoint.x, gpsPoint.y, gpsPoint.z);
var housingsNearby = getCreatures().Where(o => o.type == BotTypes.Housing && this.me.dist(o) <= maxDistanceFromGpsPoint && (!housingsScanned.Contains(o.uniqId)))
.OrderBy(o => me.dist(o)).Cast<Housing>().ToList();
housingsScanned.AddRange(housingsNearby.Select(o => o.uniqId));
Log(housingsNearby.Count() + " properties nearby.");
foreach (Housing housing in housingsNearby)
{
this.ComeTo(housing.X, housing.Y, housing.Z, minDistanceToUpdateTaxInfo, minDistanceToUpdateTaxInfo);
bool succeeded = housing.UpdateTaxInfo();
if (succeeded)
{
Log("Scanned: " + HousingInfo(housing));
if (housing.weeksWithoutPay > 0)
{
this.Log("Expiring house found!" + HousingInfo(housing), Color.Green);
expiringHousings.Add(housing);
}
}
else
{
this.Log(string.Format("Tax info could not be updated. Last error: {0}. {1}", this.GetLastError(), HousingInfo(housing)));
}
Thread.Sleep(1000);
}
}
this.Log("Land scan finished.");
this.Log(string.Format("{0} properties scanned.", housingsScanned.Count));
this.Log(string.Format("{0} properties expiring.", expiringHousings.Count));
expiringHousings.ForEach(o => Log(HousingInfo(o), Color.Green));
}
catch (Exception ex)
{
this.Log("Error: " + ex.Message, Color.Red);
}
}
private Gps ValidateAndLoadGps(string gpsFilePath, string beginPoint,string endpoint)
{
if (!File.Exists(gpsFilePath))
{
throw new FileNotFoundException("GPS file not found.");
}
Gps gps = new Gps(this);
bool succeeded = gps.LoadDataBase(gpsFilePath);
if (!succeeded)
{
throw new ApplicationException("Error while loading GPS file: " + this.GetLastError());
}
if (gps.GetPoint(endpoint) == null)
{
throw new ApplicationException(string.Format("Could not find GPS endpoint '{0}'. Make sure you have this named point in your GPS file.", endpoint));
}
if (gps.GetPoint(beginPoint) == null)
{
throw new ApplicationException(string.Format("Could not find GPS endpoint '{0}'. Make sure you have this named point in your GPS file.", beginPoint));
}
return gps;
}
private string HousingInfo(Housing housing, bool includeExpirationInfo = true)
{
string info = String.Empty;
if (includeExpirationInfo)
{
DateTime expirationDate = housing.GetExpirationDate();
info = string.Format("Expires at {0} {1}. ", expirationDate.ToShortDateString(), expirationDate.ToLongTimeString());
}
info += String.Format("Property name: {0}. Owner: {1}. Position: ({2},{3})", housing.name, housing.ownerName, housing.X, housing.Y);
return info;
}
public void PluginStop()
{
this.Log(GetPluginDescription() + " finished.");
}
}
// I tried to put any useful "standalone" code in these extesion classes that can be reused in other projects. Feel free to copy them
static class LongExtensions
{
public static DateTime UnixTimeStampToDateTime(this ulong unixTimeStamp)
{
return new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(unixTimeStamp).ToLocalTime();
}
}
static class HousingExtensions
{
public static DateTime GetExpirationDate(this Housing housing)
{
DateTime taxPaidTime = housing.taxPayedTime.UnixTimeStampToDateTime();
DateTime expirationDate = taxPaidTime.AddDays(14);
return expirationDate;
}
}
}
ChangeLog:
Code:
1.0 [9/27/2015] - Initial version