Sign in to follow this  
Followers 0
james3mg

Travian Game analysis creation tools

1 post in this topic

#1 ·  Posted (edited)

In the last few months, I've been creating a series of analyses on the forum for server 5 of travian.us with the help of some scripts I wrote. Now that that server is winding down to a close and I'm unlikely to continue playing, I wanted to share the tools with other players. However, since it's an AutoIt script, I'm going to post the source and binaries here and just link them over to this topic- that way people from both worlds can see it, if anyone wants it :)

For those who aren't familiar with Travian, it's a free, realtime MMOG war game that requires no software but a web browser to play. Players can create many villages, and belong to alliances of up to 60 people, to cooperate and win the game. Alliances then, can form confederations so that multiple alliances all identify themselves as being on the same team. Generally, if one wing (confederation) wins the game, all players in confedded wings are considered to have won as well. Therefore, various types of analyses are created by players, identifying the top alliances from all kinds of criterion, and posted on the forums for bragging rights or general information. These scripts aid greatly in creating a type of analyses I was inspired to create by another player: an analyses of which alliances are the most active, and various ways of attempting to find the targets of large offensive strikes.

Travian provides a nightly SQL "dump" representing the game world, that may be downloaded and analyzed to get an idea of what's going on in-game. Information in the dumps include player names, alliances, villages belonging to each player, and population/location of each village. Information on the format of the dump may be found here. Use of the information in the dumps is completely legal within the game's rules; data obtained automatically by other means (such as automating signing in and getting more information available in-game that is not in the dumps) are not, as a rule, legal. My scripts work strictly from data obtained from the dumps, and so remain completely legal. The side-effect is that you must download the dumps for at least 2 days before you can analyze anything.

All three of the scripts, when launched, prompt you for the MOST RECENT dump you wish to analyze, then continue prompting you for increasingly older dumps until you press the "Cancel" button, indicating you have loaded all the data you desire to analyze. They then load the SQL data into a temporary "in memory" database for querying later. It asks you also for the alliance you wish to analyze, and the threshold of population changes, below which will be counted.

In the input box requesting the alliance you wish to analyze, there are a few things I need to note.

1) it is not case-sensitive

2) the percent (%) sign, in SQL, is a wildcard standing for zero or more characters. So Aut% would include alliances named "Aut", "Autoit" and "auto it". Aut%t would include alliances named "Autt", "Autoit" and so on. You may use more than one % sign as well: Au%o% would include "Auo","auto","autoit" and so on.

3) you can use the all-caps keyword OR to include multiple alliances which are not named similarly. Auto OR It would include only alliances named "Auto" or "it", though Auto% OR It would include alliances named "Autoit", "it", "autozzzzzzz", and so on, but not "itisnt", since there's no wildcard after "It". Providing only a % in the alliance search string will return ALL players on the server, whether they are in an alliance or not.

4) (for advanced users only) users familiar with SQL can examine my call to make even more advanced analyses- for instance, to analyze only players in the alliance "AutoIt" whose X and Y village coordinates are both positive, you could input the following for the alliance search string:

AutoIt' AND `x`>'0' AND `y`>'0
(note that the entire inputted string is escaped, so leave off the first and last single-quote marks if you start searching for something besides alliance name).

Edit: it seems there's been some confusion regarding the use of these. Since they're just analyzers that look for day-to-day change, you must provide more than one day's worth of data to get more than a list of alliance members (or in the case of the mapping application, to get anything at all). ;)

Script 1: Entire account pop-change

This script goes through an alliance, player-by-player, day-by-day, and searches for players who have not grown by the minimum threshold you set in their entire account. So, if they have two villages, and one gained 10 population while the other lost 5, their day-to-day growth would be 5 in this script.

I use this script to look for large hits against players: setting the threshold to -25 allows me to find players who lost more than 25 pop in a day. Since that number is offset by any growth they have in other villages, it allows players to not be counted if they can balance their pop-loss with growth elsewhere (or if they lost pop in one place because they were tearing down an old building, but still made it up elsewhere).

Download the binary here. Source:

#include <SQLite.dll.au3>#include <SQLite.au3>_SQLite_Startup()_SQLite_Open()Global $NumDays=0Global $FileNames[1]=[0]Local $nextStr="most recent day"While 1   $NextFile=FileOpenDialog("Select "&$nextStr,@WorkingDir,"SQL dumps (*.sql)",3,"map.sql")    If @error Then ExitLoop $NumDays+=1 ReDim $FileNames[$NumDays+1]    $FileNames[$NumDays]=StringTrimLeft($NextFile,StringInStr($NextFile,"\",0,-1))  _SQLite_Exec(-1,"CREATE TABLE `x_world` (`id`,`x`,`y`,`tid`,`vid`,`village`,`uid`,`player`,`aid`,`alliance`,`population`)") _SQLite_Exec(-1,FileRead($NextFile))    _SQLite_Exec(-1,"ALTER TABLE `x_world` RENAME TO `x_world"&$NumDays&"`")    $nextStr="file "&$NumDays+1&" (last was "&$FileNames[$NumDays]&")"WEndIf $NumDays=0 Then ExitGlobal $InactiveThreshold=""While 1    $AllianceName=InputBox("Alliance","Enter the alliance to search for:")  If @error Then Exit TraySetToolTip("Analyzing total pop change of "&$AllianceName)  If $InactiveThreshold="" Then $InactiveThreshold=InputBox("Inactive Threshold","Enter the growth required to be considered ""active"":","-25")  If @error Then Exit Global $userlist,$villagelist,$userlistRows,$villagelistRows,$iCols _SQLite_GetTable2d(-1,"SELECT DISTINCT `uid` FROM `x_world1` WHERE `alliance` LIKE '"&StringReplace($AllianceName," OR ","' OR `alliance` LIKE '")&"'",$userlist,$userlistRows,$iCols)  Redim $userlist[$userlistRows+1][$NumDays+1]    Global $InactiveDaysTotal=0 Global $InactivePlayersTotal=0  Global $InactivesOnlyTable[1][$NumDays]=[[0]]   Global $GrossInactiveTotal=0    ProgressOn("Analyzing "&$AllianceName&"...","Finding accounts with less than "&$InactiveThreshold&" growth total","Step 1 of 3",Default,Default,18) For $iuser=1 To $userlistRows       ProgressSet(Round(($iuser/$userlistRows)*100))      $tmpInactive=0      $oldtmpTotal=0      For $idays=$NumDays To 1 Step -1            _SQLite_GetTable2D(-1,"SELECT `population` FROM `x_world"&$idays&"` WHERE `uid` LIKE '"&$userlist[$iuser][0]&"' ORDER BY `id`",$villageList,$villagelistRows,$iCols)            $tmpTotal=0         $userlist[$iuser][$idays]=""            For $ivillages=1 To $villagelistRows                $tmpTotal+=$villageList[$ivillages][0]              $userlist[$iuser][$idays]&=$villageList[$ivillages][0]&"<br />"         Next            $userlist[$iuser][$idays]&="<font color=""blue"">"&$tmpTotal&"</font><br />"            If $tmpTotal-$oldtmpTotal < $InactiveThreshold Then             $userlist[$iuser][$idays]&="<font color=""red"">"               $InactiveDaysTotal+=1               $tmpInactive+=1         Else                $userlist[$iuser][$idays]&="<font color=""green"">"         EndIf           $userlist[$iuser][$idays]&=$tmpTotal-$oldtmpTotal&"</font>"         $oldtmpTotal=$tmpTotal      Next        If $tmpInactive > 0 Then            $InactivePlayersTotal+=1            If $tmpInactive > 1 Then $GrossInactiveTotal+=1         ReDim $InactivesOnlyTable[UBound($InactivesOnlyTable)+1][$NumDays+1]            $InactivesOnlyTable[0][0]+=1            $InactivesOnlyTable[$InactivesOnlyTable[0][0]][0]=$userlist[$iuser][0]          For $idays=$NumDays To 1 Step -1                $InactivesOnlyTable[$InactivesOnlyTable[0][0]][$idays]=$userlist[$iuser][$idays]            Next        EndIf   Next    Global $HTMLstr="<HTML><BODY><table border=0 align=""left""><TR><TD>Results for alliance "&$AllianceName&"<TABLE border=1 align=""left""><TR><TH>Player</TH>"   For $n=$NumDays To 1 Step -1        $HTMLstr&="<TH>"&$FileNames[$n]&"</TH>" Next    $HTMLstr&="</TR>"   ProgressSet(0,"Step 2 of 3")    For $i=1 To $userlistRows       ProgressSet(Round(($i/$userlistRows)*100))      $HTMLstr&="<TR><TD>"        Local $aResult,$iRows       _SQLite_GetTable2d(-1,"SELECT DISTINCT `player` FROM `x_world1` WHERE `uid` LIKE '"&$userlist[$i][0]&"'",$aResult,$iRows,$iCols)        If $iRows < 1 Then          $HTMLstr&=$userlist[$i][0]      Else            $HTMLstr&=$aResult[1][0]        EndIf       _SQLite_GetTable2d(-1,"SELECT DISTINCT `alliance` FROM `x_world1` WHERE `uid` LIKE '"&$userlist[$i][0]&"'",$aResult,$iRows,$iCols)      If $iRows > 0 Then $HTMLstr&="<br />"&$aResult[1][0]        $HTMLstr&="</TD>"       For $idays=$NumDays To 1 Step -1            $HTMLstr&="<TD>"&$userlist[$i][$idays]&"</TD>"      Next        $HTMLstr&="</TR>"   Next    $HTMLstr&="</TABLE></TD></TR></TABLE><br />This alliance has "&$userlistRows&" players total, with "&$InactiveDaysTotal&" inactive days ("&Round(($InactiveDaysTotal/($userlistRows*($NumDays-1))*100),1)&"%) among "&$InactivePlayersTotal&" players ("&Round(($InactivePlayersTotal/$userlistRows)*100,1)&"%), "&$GrossInactiveTotal&" ("&Round(($GrossInactiveTotal/$userlistRows)*100,1)&"%) of which had more than one inactive day.<br /><TABLE border=1><TR><TH>Player</TH>" For $n=$NumDays To 1 Step -1        $HTMLstr&="<TH>"&$FileNames[$n]&"</TH>" Next    $HTMLstr&="</TR>"   ProgressSet(0,"Step 3 of 3")    For $i=1 To $InactivesOnlyTable[0][0]       ProgressSet(Round(($i/$InactivesOnlyTable[0][0])*100))      $HTMLstr&="<TR><TD>"        Local $aResult,$iRows       _SQLite_GetTable2d(-1,"SELECT DISTINCT `player` FROM `x_world1` WHERE `uid` LIKE '"&$InactivesOnlyTable[$i][0]&"'",$aResult,$iRows,$iCols)      If $iRows < 1 Then          $HTMLstr&=$userlist[$i][0]      Else            $HTMLstr&=$aResult[1][0]        EndIf       _SQLite_GetTable2d(-1,"SELECT DISTINCT `alliance` FROM `x_world1` WHERE `uid` LIKE '"&$InactivesOnlyTable[$i][0]&"'",$aResult,$iRows,$iCols)        If $iRows > 0 Then $HTMLstr&="<br />"&$aResult[1][0]        $HTMLstr&="</TD>"       For $idays=$NumDays To 1 Step -1            $HTMLstr&="<TD>"&$InactivesOnlyTable[$i][$idays]            $HTMLstr&="</TD>"       Next        $HTMLstr&="</TR>"   Next    ProgressOff()   $HTMLstr&="</BODY></HTML>"  $HTMLfile=FileSaveDialog("Save HTML analysis",@WorkingDir,"HTML files (*.html)",18,StringLeft(StringReplace($AllianceName,"%"," "),StringInStr(StringReplace($AllianceName,"%"," ")," ")-1)&".html")    If @error Then Exit If StringRight($HTMLfile,5) <> ".html" Then $HTMLfile&=".html"  $HTMLfileLink=FileOpen($HTMLfile,2) FileWrite($HTMLfileLink,$HTMLstr)   FileClose($HTMLfileLink)    Run(@comspec & " /c start """" """&$HTMLfile&"""",@WorkingDir,@SW_HIDE) If MsgBox(4,"Another alliance","Do you want to use the same data to analyze another alliance?") <> 6 Then ExitWEnd
This script, when done, will prompt you to save a .html file that contains your data. Once you save it, it will open the html file in your browser so you can see and copy the analysis.

Script 2: Village-specific positive-only growth

This script only counts those villages of a player's which had positive growth. This one is good for counting inactive players, since a player that is getting attacked and losing population shouldn't be counted the same as a player with no growth whatsoever. I usually set the threshold of this analyzer to 10- a very minimal daily population growth at nearly all phases of a server, but high enough that inactive players won't meet it. So if a player has two villages, one grows by 10 and the other shrinks by 5, they will be considered by this analyzer to have grown 10 that day, meeting the minimum activity level, even though their account as a whole only grew by 5.

Download the binary here Source:

#include <SQLite.dll.au3>#include <SQLite.au3>_SQLite_Startup()_SQLite_Open()Global $NumDays=0Global $FileNames[1]=[0]Local $nextStr="most recent day"While 1   $NextFile=FileOpenDialog("Select "&$nextStr,@WorkingDir,"SQL dumps (*.sql)",3,"map.sql")    If @error Then ExitLoop $NumDays+=1 ReDim $FileNames[$NumDays+1]    $FileNames[$NumDays]=StringTrimLeft($NextFile,StringInStr($NextFile,"\",0,-1))  _SQLite_Exec(-1,"CREATE TABLE `x_world` (`id`,`x`,`y`,`tid`,`vid`,`village`,`uid`,`player`,`aid`,`alliance`,`population`)") _SQLite_Exec(-1,FileRead($NextFile))    _SQLite_Exec(-1,"ALTER TABLE `x_world` RENAME TO `x_world"&$NumDays&"`")    $nextStr="file "&$NumDays+1&" (last was "&$FileNames[$NumDays]&")"WEndIf $NumDays=0 Then ExitGlobal $InactiveThreshold=""While 1    $AllianceName=InputBox("Alliance","Enter the alliance to search for:")  If @error Then Exit TraySetToolTip("Analyzing growth only of "&$AllianceName)   If $InactiveThreshold="" Then $InactiveThreshold=InputBox("Inactive Threshold","Enter the growth required to be considered ""active"":","10")   If @error Then Exit Global $userlist,$villagelist,$userlistRows,$villagelistRows,$poplist,$poplistRows,$iCols   _SQLite_GetTable2d(-1,"SELECT DISTINCT `uid` FROM `x_world1` WHERE `alliance` LIKE '"&StringReplace($AllianceName," OR ","' OR `alliance` LIKE '")&"'",$userlist,$userlistRows,$iCols)  Redim $userlist[$userlistRows+1][$NumDays+1]    Global $InactiveDaysTotal=0 Global $InactivePlayersTotal=0  Global $InactivesOnlyHTML   Global $MainTableHTML   Global $RecurrantInactives=0    ProgressOn("Analyzing "&$AllianceName&"...","Finding pos. growth only less than "&$InactiveThreshold,"",Default,Default,18) $MainTableHTML=""   $InactivesOnlyHTML=""   For $iuser=1 To $userlistRows       ProgressSet(Round(($iuser/$userlistRows)*100))      $tmpSelStr="SELECT DISTINCT `vid` FROM `x_world1` WHERE `uid` LIKE '"&$userlist[$iuser][0]&"'"      For $idays=2 To $NumDays            $tmpSelStr&=" UNION SELECT DISTINCT `vid` FROM `x_world"&$idays&"` WHERE `uid` LIKE '"&$userlist[$iuser][0]&"'"     Next        $tmpSelStr&=" ORDER BY `vid`"       _SQLite_GetTable2d(-1,$tmpSelStr,$villageList,$villagelistRows,$iCols)              $tmpHTMLstr="<TR><TD rowspan="""&$villagelistRows+2&""">"       Local $aResult,$iRows       _SQLite_GetTable2d(-1,"SELECT DISTINCT `player`,`alliance` FROM `x_world1` WHERE `uid` LIKE '"&$userlist[$iuser][0]&"'",$aResult,$iRows,$iCols)     If $iRows < 1 Then          $tmpHTMLstr=$userlist[$iuser][0]        Else            $tmpHTMLstr&=$aResult[1][0]&"<br />"&$aResult[1][1]     EndIf       $tmpHTMLstr&="</TD></TR>"               Dim $todayPop[$NumDays+1][$villagelistRows+1]       Dim $todayChange[$NumDays+1][$villagelistRows+1]        For $ivillages=1 To $villagelistRows            $tmpHTMLstr&="<TR>"         For $idays=$NumDays To 1 Step -1                _SQLite_GetTable2d(-1,"SELECT `population` FROM `x_world"&$idays&"` WHERE `vid` LIKE '"&$villageList[$ivillages][0]&"' AND `uid` LIKE '"&$userlist[$iuser][0]&"'",$poplist,$poplistRows,$iCols)             If $poplistRows=0 Then                  ReDim $poplist[2][1]                    $poplist[1][0]=0                EndIf               $tmpHTMLstr&="<TD>"&$poplist[1][0]              $todayPop[$idays][$ivillages]=$poplist[1][0]                If $idays=$NumDays Then                 $todayChange[$idays][$ivillages]=$poplist[1][0]             ElseIf $poplist[1][0]-$todayPop[$idays+1][$ivillages] > 0 Then                  $tmpHTMLstr&=" <FONT color=""green"">("&$poplist[1][0]-$todayPop[$idays+1][$ivillages]&")</font>"                   $todayChange[$idays][$ivillages]=$poplist[1][0]-$todayPop[$idays+1][$ivillages]             Else                    If $poplist[1][0]-$todayPop[$idays+1][$ivillages] <> 0 Then $tmpHTMLstr&=" <FONT color=""red"">("&$poplist[1][0]-$todayPop[$idays+1][$ivillages]&")</font>"                 $todayChange[$idays][$ivillages]=$poplist[1][0]-$todayPop[$idays+1][$ivillages]             EndIf               $tmpHTMLstr&="</TD>"            Next            $tmpHTMLstr&="</TR>"        Next        Local $tmpInactive=0        Local $tmpRecurrant=0       $tmpHTMLstr&="<TR><TD>&nbsp;</TD>"      For $idays=$NumDays-1 To 1 Step -1          local $poschange=0          local $negchange=0          For $ivillages=1 To $villagelistRows                If $todayChange[$idays][$ivillages] > 0 Then $poschange+=$todayChange[$idays][$ivillages]               If $todayChange[$idays][$ivillages] < 0 Then $negchange-=$todayChange[$idays][$ivillages]           Next            If $poschange < $InactiveThreshold Then             $tmpInactive=1              $InactiveDaysTotal+=1               $tmpRecurrant+=1            EndIf           If $posChange < $InactiveThreshold Then             $tmpHTMLstr&="<TD bgcolor=""yellow""><FONT color=""green"">"&$poschange&"</font>-<FONT color=""red"">"&$negchange&"</font>=<FONT color=""red"">"&$poschange-$negchange&"</font></TD>"           Else                $tmpHTMLstr&="<TD bgcolor=""CCCCFF""><FONT color=""green"">"&$poschange&"</font>-<FONT color=""red"">"&$negchange&"</font>="&$poschange-$negchange&"</TD>"          EndIf       Next        $tmpHTMLstr&="</TR>"        $MainTableHTML&=$tmpHTMLstr     If $tmpInactive=1 Then $InactivesOnlyHTML&=$tmpHTMLstr      $InactivePlayersTotal+=$tmpInactive     If $tmpRecurrant>1 Then $RecurrantInactives+=1  Next    $MainTableHTML&="</TABLE>"  $InactivesOnlyHTML&="</TABLE>"  ProgressOff()   Global $HTMLstr="<HTML><BODY>Results for alliance "&$AllianceName&"<TABLE border=1 align=""left""><TR><TH>Player</TH>"  For $n=$NumDays To 1 Step -1        $HTMLstr&="<TH>"&$FileNames[$n]&"</TH>" Next    $HTMLstr&="</TR>"   $HTMLstr&=$MainTableHTML&"<br />This alliance has "&$userlistRows&" players total, with "&$InactiveDaysTotal&" inactive days ("&Round($InactiveDaysTotal/(($NumDays-1)*$userlistRows),3)*100&"%) among "&$InactivePlayersTotal&" players ("&Round($InactivePlayersTotal/$userlistRows,3)*100&"%), "&$RecurrantInactives&" of which ("&Round($RecurrantInactives/$userlistRows,3)*100&"%) had more than one inactive day.<br /><TABLE border=1>"&$InactivesOnlyHTML  $HTMLstr&="</BODY></HTML>"  $HTMLfile=FileSaveDialog("Save HTML analysis",@WorkingDir,"HTML files (*.html)",18,StringLeft(StringReplace($AllianceName,"%"," "),StringInStr(StringReplace($AllianceName,"%"," ")," ")-1)&".html")    If @error Then Exit If StringRight($HTMLfile,5) <> ".html" Then $HTMLfile&=".html"  $HTMLfileLink=FileOpen($HTMLfile,2) FileWrite($HTMLfileLink,$HTMLstr)   FileClose($HTMLfileLink)    Run(@comspec & " /c start """" """&$HTMLfile&"""",@WorkingDir,@SW_HIDE) If MsgBox(4,"Another alliance","Do you want to use the same data to analyze another alliance?") <> 6 Then ExitWEnd
This script, when done, will prompt you to save a .html file that contains your data. Once you save it, it will open the html file in your browser so you can see and copy the analysis.

Script 3: Population loss mapper

This script actually draws a map of villages which lost more than your threshold level's minimum population day-to-day. The larger the dots are, the more population was lost from that village, and the more opaque the dot, the more days total it lost population. Once the map comes up, right-click it to be allowed to save the image or save/copy the data used to create the map. If you copy the data to the clipboard, paste it into notepad, find-n-replace "|" with "," and save it as a .csv file, it can be opened in Excel for some great graph making abilities.

Download the binary here Source:

#include <SQLite.dll.au3>#include <SQLite.au3>#include <GdiPlus.au3>#include <Array.au3>_SQLite_Startup()_SQLite_Open()_GDIPlus_Startup()Global $NumDays=0Global $FileNames[1]=[0]Local $nextStr="most recent day"While 1   $NextFile=FileOpenDialog("Select "&$nextStr,@WorkingDir,"SQL dumps (*.sql)",3,"map.sql")    If @error Then ExitLoop $NumDays+=1 ReDim $FileNames[$NumDays+1]    $FileNames[$NumDays]=StringTrimLeft($NextFile,StringInStr($NextFile,"\",0,-1))  _SQLite_Exec(-1,"CREATE TABLE `x_world` (`id`,`x`,`y`,`tid`,`vid`,`village`,`uid`,`player`,`aid`,`alliance`,`population`)") _SQLite_Exec(-1,FileRead($NextFile))    _SQLite_Exec(-1,"ALTER TABLE `x_world` RENAME TO `x_world"&$NumDays&"`")    $nextStr="file "&$NumDays+1&" (last was "&$FileNames[$NumDays]&")"WEndIf $NumDays=0 Then ExitGlobal $InactiveThreshold=""$AllianceName=InputBox("Alliance","Enter the alliance to search for:")If @error Then ExitTraySetToolTip("Mapping "&$AllianceName)$DotColor=InputBox("Color","Enter the hex code for the color you want this alliance's dots to be:",StringRight(Hex(Random(0x000000,0xFFFFFF,1)),6))If @error Then ExitIf $InactiveThreshold="" Then $InactiveThreshold=InputBox("Inactive Threshold","Enter the population change below which will be mapped:")If @error Then ExitGlobal $villagelist,$villagelistRows,$poplist,$poplistRows,$iColsGlobal $map[1][4];x,y,size,number$map[0][0]=0ProgressOn("Mapping "&$AllianceName&"...","","Finding villages...",Default,Default,18)$tmpSelStr="SELECT DISTINCT `vid`,`x`,`y` FROM `x_world1` WHERE `alliance` LIKE '"&StringReplace($AllianceName," OR ","' OR `alliance` LIKE '")&"'"For $idays=2 To $NumDays $tmpSelStr&=" UNION SELECT DISTINCT `vid`,`x`,`y` FROM `x_world"&$idays&"` WHERE `alliance` LIKE '"&StringReplace($AllianceName," OR ","' OR `alliance` LIKE '")&"'"Next$tmpSelStr&=" ORDER BY `vid`"_SQLite_GetTable2d(-1,$tmpSelStr,$villageList,$villagelistRows,$iCols)Dim $todayPop[$NumDays+1][$villagelistRows+1]Dim $todayChange[$NumDays+1][$villagelistRows+1]For $ivillages=1 To $villagelistRows    ProgressSet(Round(($ivillages/$villagelistRows)*100),$map[0][0]&" hits mapped") $tmpInactive=0  $tmpChange=0    For $idays=$NumDays To 1 Step -1        _SQLite_GetTable2d(-1,"SELECT `population` FROM `x_world"&$idays&"` WHERE `vid` LIKE '"&$villageList[$ivillages][0]&"' AND (`alliance` LIKE '"&StringReplace($AllianceName," OR ","' OR `alliance` LIKE '")&"')",$poplist,$poplistRows,$iCols)      If $poplistRows=0 Then          Dim $poplist[2][1]          $poplist[1][0]=0        EndIf       $todayPop[$idays][$ivillages]=$poplist[1][0]        If $idays<>$NumDays AND $poplist[1][0]-$todayPop[$idays+1][$ivillages] < $InactiveThreshold Then            $tmpInactive+=1         $tmpChange+=$poplist[1][0]-$todayPop[$idays+1][$ivillages]      EndIf   Next    If $tmpInactive>0 Then      $map[0][0]+=1       ReDim $map[$map[0][0]+1][4]     $map[$map[0][0]][0]=$villageList[$ivillages][1]     $map[$map[0][0]][1]=$villageList[$ivillages][2]     $map[$map[0][0]][2]=Abs($tmpChange)     $map[$map[0][0]][3]=$tmpInactive    EndIfNextProgressOff()Global $GUI=GUICreate($AllianceName,820,820)$ContextMenu=GUICtrlCreateContextMenu()$SavePicture=GUICtrlCreateMenuItem("Save picture",$ContextMenu)$Info=GUICtrlCreateMenuItem("Show Data",$ContextMenu)GUISetState()$graphic1 = _GDIPlus_GraphicsCreateFromHWND($GUI)$hBMP = _GDIPlus_BitmapCreateFromGraphics(820, 820, $graphic1)$graphic2 = _GDIPlus_ImageGetGraphicsContext($hBMP)$pColor=_GDIPlus_BrushCreateSolid("0xFFFFFFFF")_GDIPlus_GraphicsFillRect($graphic2,0,0,820,820,$pColor)_GDIPlus_BrushDispose($pColor)#Region Grid$pColor=_GDIPlus_PenCreate("0xFF999999");50 linesFor $i=0 To 16    _GDIPlus_GraphicsDrawLine($graphic2, $i*50+10,10,$i*50+10,810,$pColor)  _GDIPlus_GraphicsDrawLine($graphic2, 10,$i*50+10,810,$i*50+10,$pColor)Next_GDIPlus_PenDispose($pColor)$pColor=_GDIPlus_PenCreate("0xFFDDDDDD");25 linesFor $i=0 To 15   _GDIPlus_GraphicsDrawLine($graphic2, $i*50+35,10,$i*50+35,810,$pColor)  _GDIPlus_GraphicsDrawLine($graphic2, 10,$i*50+35,810,$i*50+35,$pColor)Next_GDIPlus_PenDispose($pColor)$pColor=_GDIPlus_PenCreate("0xFF000000");16th lines_GDIPlus_GraphicsDrawLine($graphic2, 210,10,210,810,$pColor)_GDIPlus_GraphicsDrawLine($graphic2, 10,210,810,210,$pColor)_GDIPlus_GraphicsDrawLine($graphic2, 610,10,610,810,$pColor)_GDIPlus_GraphicsDrawLine($graphic2, 10,610,810,610,$pColor)_GDIPlus_PenDispose($pColor)$pColor=_GDIPlus_PenCreate("0xFF000000",2);quad lines_GDIPlus_GraphicsDrawLine($graphic2, 410,10,410,810,$pColor)_GDIPlus_GraphicsDrawLine($graphic2, 10,410,810,410,$pColor)_GDIPlus_PenDispose($pColor)#EndRegion Grid$pColor_outl=_GDIPlus_PenCreate("0xFF000000",1)For $i=1 To $map[0][0]  $pColor=_GDIPlus_BrushCreateSolid("0x"&Hex(Round(255*($map[$i][3]/$NumDays)),2)&StringRight($DotColor,6))   _GDIPlus_GraphicsFillEllipse($graphic2,($map[$i][0]+410)-Ceiling($map[$i][2]/80),($map[$i][1]*-1+410)-Ceiling($map[$i][2]/80),Ceiling($map[$i][2]/40),Ceiling($map[$i][2]/40),$pColor)  _GDIPlus_GraphicsDrawEllipse($graphic2,($map[$i][0]+410)-Ceiling($map[$i][2]/80),($map[$i][1]*-1+410)-Ceiling($map[$i][2]/80),Ceiling($map[$i][2]/40),Ceiling($map[$i][2]/40),$pColor_outl) _GDIPlus_BrushDispose($pColor)Next_GDIPlus_PenDispose($pColor_outl)_GDIPlus_GraphicsDispose($graphic2)_GDIPlus_GraphicsDrawImageRect($graphic1, $hBMP, 0, 0, 820, 820)$map[0][0]="x"$map[0][1]="y"$map[0][2]="pop loss"$map[0][3]="# of hits"Do _GDIPlus_GraphicsDrawImageRect($graphic1, $hBMP, 0, 0, 820, 820)    $msg=GUIGetMsg()    If $msg<0 Then ContinueLoop If $msg=$SavePicture Then       $SaveFile=FileSaveDialog("Save image as...","","jpg image (*.jpg)",18,"AllianceMap.jpg")        If NOT @error Then          If StringRight($SaveFile,4) <> ".jpg" Then $SaveFile&=".jpg"            _GDIPlus_ImageSaveToFile($hBMP, $SaveFile)      EndIf   EndIf   If $msg=$Info Then _ArrayDisplay($map)  sleep(15)Until $msg = -3

An example of the analyses I create with these three scripts can be found here if you're interested.

A few more notes on the scripts themselves: they don't leave any files on your system (other than the files you choose to save the data in), but it uses the SQLite library for parsing the information, which registeres a very small, harmless .dll on your system. There are two implications of this:

1) to "uninstall" a script, just delete it. Leaving the sqlite library on your system can't hurt anything. However, if you want to get rid of it as well, search on the forums here- there are topics discussing the unregistration of COM files.

2) You may need to run the scripts as administrator the first time, so it has permission to register the dll.

Finally, a precaution: these can take a while to crunch all the numbers. It shouldn't be more than an hour per analyses, even on older machines, but I don't recommend running more instances of any of these programs that you've got processors! Your computer will not like you. And all bets are off if you run an analysis of an entire server (by providing % as the alliance string)- that's just going to take quite a while. I did it once, and it took several hours on a dual-core machine. My 8 core beast at home smokes through these pretty well, however.

I think that covers everything- let me know if you have questions! B)

Edited by james3mg

"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110

Share this post


Link to post
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0