public void CheckForPluginUpdate()
{
// runs in one-shot thread
try {
lock (fUpdateThreadLock) {
fUpdateThreadLock.MaxDelay = fUpdateThreadLock.MaxDelay + 1;
fUpdateThreadLock.LastUpdate = DateTime.Now;
}
XmlDocument xml = new XmlDocument();
try {
xml.Load("https://myrcon.com/procon/plugins/report/format/xml/plugin/MULTIbalancer");
} catch (System.Security.SecurityException e) {
if (DebugLevel >= 8) ConsoleException(e);
ConsoleWrite(" ", 0);
ConsoleWrite("^8^bNOTICE! Unable to check for plugin update!", 0);
ConsoleWrite("Tools => Options... => Plugins tab: ^bPlugin security^n is set to ^bRun plugins in a sandbox^n.", 0);
//ConsoleWrite("Please add ^bmyrcon.com^n to your trusted ^bOutgoing connections^n");
ConsoleWrite("Consider changing to ^bRun plugins with no restrictions.^n", 0);
ConsoleWrite("Alternatively, check the ^bPlugins^n forum for an update to this plugin.", 0);
ConsoleWrite(" ", 0);
return;
}
if (DebugLevel >= 8) ConsoleDebug("CheckForPluginUpdate: Got " + xml.BaseURI);
/*
Example:
<report>
<id>5132671</id>
<plugin>
<id>478344</id>
<uid>MultiBalancer</uid>
<name>MULTI-balancer</name>
</plugin>
<version>
<id>965536</id>
<major>1</major>
<minor>0</minor>
<maintenance>0</maintenance>
<build>1</build>
</version>
<sum_in_use>22</sum_in_use>
<avg_in_use>22.0000</avg_in_use>
<max_in_use>22</max_in_use>
<min_in_use>22</min_in_use>
<stamp>2013-05-10 10:00:04</stamp>
</report>
*/
XmlNodeList rows = xml.SelectNodes("//report");
if (DebugLevel >= 8) ConsoleDebug("CheckForPluginUpdate: # rows = " + rows.Count);
if (rows.Count == 0) return;
Dictionary<String,int> versions = new Dictionary<String,int>();
foreach (XmlNode tr in rows) {
XmlNode ver = tr.SelectSingleNode("version");
//XmlNode count = tr.SelectSingleNode("sum_in_use");
XmlNode count = tr.SelectSingleNode("max_in_use");
if (DebugLevel >= 8) ConsoleDebug("CheckForPluginUpdate: using max_in_use");
if (ver != null && count != null) {
int test = 0;
XmlNode major = ver.SelectSingleNode("major");
if (major != null && !Int32.TryParse(major.InnerText, out test)) continue;
XmlNode minor = ver.SelectSingleNode("minor");
if (minor != null && !Int32.TryParse(minor.InnerText, out test)) continue;
XmlNode maint = ver.SelectSingleNode("maintenance");
if (maint != null && !Int32.TryParse(maint.InnerText, out test)) continue;
XmlNode build = ver.SelectSingleNode("build");
if (build != null && !Int32.TryParse(build.InnerText, out test)) continue;
String vt = major.InnerText + "." + minor.InnerText + "." + maint.InnerText + "." + build.InnerText;
if (DebugLevel >= 8) ConsoleDebug("CheckForPluginUpdate: Version: " + vt + ", Count: " + count.InnerText);
int n = 0;
if (!Int32.TryParse(count.InnerText, out n)) continue;
versions[vt] = n;
}
}
// Select current version and any "later" versions
int usage = 0;
String myVersion = GetPluginVersion();
if (!versions.TryGetValue(myVersion, out usage)) {
DebugWrite("CheckForPluginUpdate: " + myVersion + " not found!", 8);
return;
}
// numeric sort
List<String> byNumeric = new List<String>();
byNumeric.AddRange(versions.Keys);
// Sort numerically descending
byNumeric.Sort(delegate(String lhs, String rhs) {
if (lhs == rhs) return 0;
if (String.IsNullOrEmpty(lhs)) return 1;
if (String.IsNullOrEmpty(rhs)) return -1;
uint l = VersionToNumeric(lhs);
uint r = VersionToNumeric(rhs);
if (l < r) return 1;
if (l > r) return -1;
return 0;
});
DebugWrite("CheckForPluginUpdate: sorted version list:", 7);
foreach (String u in byNumeric) {
DebugWrite(u + " (" + String.Format("{0:X8}", VersionToNumeric(u)) + "), count = " + versions[u], 7);
}
int position = byNumeric.IndexOf(myVersion);
DebugWrite("CheckForPluginUpdate: found " + position + " newer versions", 5);
if (position != 0) {
// Newer versions found
// Find the newest version with the largest number of usages
int hasMost = -1;
int most = 0;
for (int i = position-1; i >= 0; --i) {
int newerVersionCount = versions[byNumeric[i]];
if (hasMost == -1 || most < newerVersionCount) {
// Skip newer versions that don't have enough usage yet
if (most > 0 && newerVersionCount < MIN_UPDATE_USAGE_COUNT) continue;
hasMost = i;
most = versions[byNumeric[i]];
}
}
if (hasMost != -1 && hasMost < byNumeric.Count && most >= MIN_UPDATE_USAGE_COUNT) {
String newVersion = byNumeric[hasMost];
ConsoleWrite("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", 0);
ConsoleWrite(" ", 0);
ConsoleWrite("^8^bA NEW VERSION OF THIS PLUGIN IS AVAILABLE!", 0);
ConsoleWrite(" ", 0);
ConsoleWrite("^8^bPLEASE UPDATE TO VERSION: ^0" + newVersion, 0);
ConsoleWrite(" ", 0);
ConsoleWrite("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", 0);
TaskbarNotify(GetPluginName() + ": new version available!", "Please download and install " + newVersion);
}
}
} catch (ThreadAbortException) {
fAborted = true;
return;
} catch (Exception e) {
if (!fAborted) ConsoleException(e);
} finally {
if (!fAborted) {
// Update check time
fLastVersionCheckTimestamp = DateTime.Now;
// Update traffic control
lock (fUpdateThreadLock) {
fUpdateThreadLock.MaxDelay = fUpdateThreadLock.MaxDelay - 1;
fUpdateThreadLock.LastUpdate = DateTime.MinValue;
}
DebugWrite("Updater thread finished!", 3);
}
}
}