1- using System . IO ;
1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Diagnostics ;
4+ using System . IO ;
5+ using System . Linq ;
6+ using System . Reflection ;
27using BepInEx ;
38using BepInEx . Configuration ;
9+ using BepInEx . Logging ;
410using UnityEngine ;
511using RoR2 ;
612using RoR2 . Stats ;
713using UnityEngine . Networking ;
814using System . Threading . Tasks ;
15+ using Console = RoR2 . Console ;
16+ using Debug = UnityEngine . Debug ;
17+ using Path = System . IO . Path ;
918
1019
1120namespace BotCMDs
1221{
1322 [ BepInDependency ( "com.bepis.r2api" ) ]
14- [ BepInPlugin ( "com.Rayss.BotCommands" , "BotCommands" , "0.2 .0" ) ]
23+ [ BepInPlugin ( "com.Rayss.BotCommands" , "BotCommands" , "0.3 .0" ) ]
1524 public class BotCommands : BaseUnityPlugin
1625 {
1726 // Config
1827 private static ConfigEntry < string > Cmdpath { get ; set ; }
19- private string botcmd_path ;
28+ private string _botcmdPath ;
29+ private static ConfigEntry < string > Servername { get ; set ; }
30+ private static string _serverName ;
31+ // Create custom log source
32+ private static ManualLogSource Log = new ManualLogSource ( "BotCommands" ) ;
2033
2134 [ System . Diagnostics . CodeAnalysis . SuppressMessage ( "Code Quality" , "IDE0051:Remove unused private members" ) ]
2235 private void Awake ( )
2336 {
37+ // Register custom log source
38+ BepInEx . Logging . Logger . Sources . Add ( Log ) ;
39+
40+ // Path is the current path of the .DLL
41+ var path = Path . GetDirectoryName ( Assembly . GetExecutingAssembly ( ) . Location ) ;
2442 Cmdpath = Config . Bind < string > (
25- "Config" ,
26- "botcmd" ,
27- "C:/Program Files (x86)/Steam/steamapps/common/Risk of Rain 2 Dedicated Server/BepInEx/plugins/ botcmd.txt",
28- "Insert the path of your botcmd.txt"
43+ "Config" ,
44+ "botcmd" ,
45+ path + @"\ botcmd.txt",
46+ "Insert the path of your botcmd.txt"
2947 ) ;
30- botcmd_path = Cmdpath . Value ;
48+ _botcmdPath = Cmdpath . Value ;
49+ Servername = Config . Bind < string > (
50+ "Config" ,
51+ "Server Name" ,
52+ "Server1" ,
53+ "Enter the name of your server for stats tracking"
54+ ) ;
55+ _serverName = Servername . Value ;
3156
32- Debug . Log ( "Created by Rayss and InfernalPlacebo." ) ;
57+ Log . LogInfo ( "Created by Rayss and InfernalPlacebo." ) ;
58+ #if DEBUG
59+ Log . LogWarning ( "You are using a debug build!" ) ;
60+ #endif
3361 }
3462
3563 [ System . Diagnostics . CodeAnalysis . SuppressMessage ( "Code Quality" , "IDE0051:Remove unused private members" ) ]
3664 private void Start ( )
3765 {
3866 StartHooks ( ) ;
3967 Reading ( ) ;
68+ OpenExe ( ) ;
4069 }
4170
4271 private async void Reading ( )
4372 {
44- using ( StreamReader reader = new StreamReader ( new FileStream ( botcmd_path ,
73+ // Create botcmd.txt if it doesn't exist yet
74+ using ( StreamWriter w = File . AppendText ( _botcmdPath ) )
75+
76+ using ( StreamReader reader = new StreamReader ( new FileStream ( _botcmdPath ,
4577 FileMode . Open , FileAccess . Read , FileShare . ReadWrite ) ) )
4678 {
4779 //start at the end of the file
4880 long lastMaxOffset = reader . BaseStream . Length ;
49- string line ;
5081
5182 while ( true )
5283 {
@@ -56,6 +87,7 @@ private async void Reading()
5687 reader . BaseStream . Seek ( lastMaxOffset , SeekOrigin . Begin ) ;
5788
5889 //read out of the file until the EOF
90+ string line ;
5991 while ( ( line = reader . ReadLine ( ) ) != null )
6092 {
6193 // Exception handling, I guess
@@ -65,7 +97,7 @@ private async void Reading()
6597 }
6698 catch
6799 {
68- Debug . Log ( "No sir, partner." ) ;
100+ Log . LogWarning ( "No sir, partner." ) ;
69101 }
70102 }
71103
@@ -75,8 +107,7 @@ private async void Reading()
75107 }
76108 }
77109
78-
79- public static void StartHooks ( )
110+ private static void StartHooks ( )
80111 {
81112 // On run end
82113 // LogTime and LogStagesCleared won't be needed after stats are done
@@ -115,23 +146,19 @@ public static void StartHooks()
115146 On . RoR2 . FadeToBlackManager . OnSceneUnloaded += ( orig , run ) =>
116147 {
117148 orig ( run ) ;
118- if ( Run . instance )
119- {
120- LogTime ( ) ;
121- LogStagesCleared ( ) ;
122- }
149+ if ( ! Run . instance ) return ;
150+ LogTime ( ) ;
151+ LogStagesCleared ( ) ;
123152 } ;
124153
125154 // On player join
126155 // Will be removed on new stat tracking
127156 On . RoR2 . Networking . GameNetworkManager . OnServerConnect += ( orig , run , conn ) =>
128157 {
129158 orig ( run , conn ) ;
130- if ( Run . instance )
131- {
132- LogTime ( ) ;
133- LogStagesCleared ( ) ;
134- }
159+ if ( ! Run . instance ) return ;
160+ LogTime ( ) ;
161+ LogStagesCleared ( ) ;
135162 } ;
136163 }
137164
@@ -158,33 +185,93 @@ private static void LogStagesCleared()
158185 private static void GetStats ( NetworkUser user )
159186 {
160187 GameObject playerMasterObject = user . masterObject ;
188+ long steamId = System . Convert . ToInt64 ( user . id . steamId . ToString ( ) ) ;
161189 StatSheet statSheet ;
162190 PlayerStatsComponent component = playerMasterObject . GetComponent < PlayerStatsComponent > ( ) ;
163191 statSheet = ( component ? . currentStats ) ;
164- // Print the statsheet to console / log
165- // Will be changing this to parse and add to the database
192+ List < string > listOfStatNames = new List < string >
193+ {
194+ "totalTimeAlive" ,
195+ "totalKills" ,
196+ "totalDeaths" ,
197+ "totalGoldCollected" ,
198+ "totalDistanceTraveled" ,
199+ "totalItemsCollected" ,
200+ "totalStagesCompleted" ,
201+ "totalPurchases"
202+ } ;
203+ Dictionary < string , string > outputStats = new Dictionary < string , string > ( ) ;
204+ Dictionary < string , string > sendToDynamo = new Dictionary < string , string > ( ) ;
166205 // Don't need all the stats they access though, should only use some of the fields (may be able to split up by category)
167206 string [ ] array = new string [ statSheet . fields . Length ] ;
168207 for ( int i = 0 ; i < array . Length ; i ++ )
169208 {
170209 array [ i ] = string . Format ( "[\" {0}\" ]={1}" , statSheet . fields [ i ] . name , statSheet . fields [ i ] . ToString ( ) ) ;
210+ outputStats [ statSheet . fields [ i ] . name ] = statSheet . fields [ i ] . ToString ( ) ;
211+ }
212+ foreach ( var kvp in outputStats . Where ( kvp => listOfStatNames . Contains ( kvp . Key ) ) )
213+ {
214+ sendToDynamo [ kvp . Key ] = kvp . Value ;
215+ }
216+ // Debug.Log(string.Join("\n", array)); <<<<< Used for seeing all the stat options
217+ // Argument organization: serverName, ID, timeAlive, kills, deaths, goldCollected, distanceTraveled, itemsCollected, stagesCompleted, purchases
218+ // Use ProcessStartInfo class
219+ var path = Path . GetDirectoryName ( Assembly . GetExecutingAssembly ( ) . Location ) ;
220+ ProcessStartInfo startInfo = new ProcessStartInfo ( ) ;
221+ startInfo . CreateNoWindow = true ;
222+ startInfo . UseShellExecute = false ;
223+ startInfo . FileName = path + @"\BotCommands_Dynamo.exe" ;
224+ startInfo . WindowStyle = ProcessWindowStyle . Hidden ;
225+ startInfo . Arguments = string . Format ( "{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}" , _serverName , steamId ,
226+ sendToDynamo [ "totalTimeAlive" ] , sendToDynamo [ "totalKills" ] , sendToDynamo [ "totalDeaths" ] ,
227+ sendToDynamo [ "totalGoldCollected" ] , sendToDynamo [ "totalDistanceTraveled" ] ,
228+ sendToDynamo [ "totalItemsCollected" ] , sendToDynamo [ "totalStagesCompleted" ] ,
229+ sendToDynamo [ "totalPurchases" ] ) ;
230+
231+ try
232+ {
233+ // Start the process with the info we specified.
234+ using ( Process exeProcess = Process . Start ( startInfo ) )
235+ {
236+ Log . LogInfo ( "BotCommands: Updating stats database!" ) ;
237+ }
238+ }
239+ catch
240+ {
241+ Log . LogError ( "BotCommands: Unable to find executable file!" ) ;
171242 }
172- // Literally all I have to do is parse the array to be used by the db
173- Debug . Log ( string . Join ( "\n " , array ) ) ;
174243 }
175244
176- // Borrowed from R2DSEssentials.Util.Networking
177- private static NetworkUser FindNetworkUserForConnectionServer ( NetworkConnection connection )
245+ // Used for debugging database
246+ [ Conditional ( "DEBUG" ) ]
247+ private static void OpenExe ( )
178248 {
179- foreach ( var networkUser in NetworkUser . readOnlyInstancesList )
249+ var path = Path . GetDirectoryName ( Assembly . GetExecutingAssembly ( ) . Location ) ;
250+ ProcessStartInfo startInfo = new ProcessStartInfo ( ) ;
251+ startInfo . CreateNoWindow = true ;
252+ startInfo . UseShellExecute = false ;
253+ startInfo . FileName = path + @"\BotCommands_Dynamo.exe" ;
254+ startInfo . WindowStyle = ProcessWindowStyle . Hidden ;
255+ startInfo . Arguments = "server9 123456789 100 100 100 100 100 100 100 100" ;
256+
257+ try
180258 {
181- if ( networkUser . connectionToClient == connection )
259+ // Start the process with the info we specified.
260+ using ( Process exeProcess = Process . Start ( startInfo ) )
182261 {
183- return networkUser ;
262+ Log . LogWarning ( "BotCommands: Updating stats database!" ) ;
184263 }
185264 }
265+ catch
266+ {
267+ Log . LogError ( "BotCommands: Unable to find executable file!" ) ;
268+ }
269+ }
186270
187- return null ;
271+ // Borrowed from R2DSEssentials.Util.Networking
272+ private static NetworkUser FindNetworkUserForConnectionServer ( NetworkConnection connection )
273+ {
274+ return NetworkUser . readOnlyInstancesList . FirstOrDefault ( networkUser => networkUser . connectionToClient == connection ) ;
188275 }
189276 }
190277}
0 commit comments