1- using BepInEx ;
1+ using System . IO ;
2+ using BepInEx ;
23using BepInEx . Configuration ;
3- using System . IO ;
4- using System . Threading . Tasks ;
54using UnityEngine ;
5+ using RoR2 ;
6+ using RoR2 . Stats ;
7+ using UnityEngine . Networking ;
8+ using System . Threading . Tasks ;
9+
610
711namespace BotCMDs
812{
913 [ BepInDependency ( "com.bepis.r2api" ) ]
10- [ BepInPlugin ( "com.Rayss.BotCommands" , "BotCommands" , "0.1.1 " ) ]
14+ [ BepInPlugin ( "com.Rayss.BotCommands" , "BotCommands" , "0.2.0 " ) ]
1115 public class BotCommands : BaseUnityPlugin
1216 {
1317 // Config
@@ -59,5 +63,102 @@ private async void Reading()
5963 }
6064 }
6165 }
66+
67+
68+ public static void InitializeHooks ( )
69+ {
70+ // On run end
71+ On . RoR2 . RunReport . Generate += ( orig , run , resulttype ) =>
72+ {
73+ RunReport valid = orig ( run , resulttype ) ; // Required if the hooked command has a return value
74+ LogTime ( ) ;
75+ LogStagesCleared ( ) ;
76+ return valid ; // Required if the hooked command has a return value
77+ } ;
78+
79+ // On scene change (unloaded, new scene not yet loaded)
80+ On . RoR2 . FadeToBlackManager . OnSceneUnloaded += ( orig , run ) =>
81+ {
82+ orig ( run ) ;
83+ if ( Run . instance )
84+ {
85+ LogTime ( ) ;
86+ LogStagesCleared ( ) ;
87+ }
88+ } ;
89+
90+ // On player join
91+ On . RoR2 . Networking . GameNetworkManager . OnServerConnect += ( orig , run , conn ) =>
92+ {
93+ orig ( run , conn ) ;
94+ if ( Run . instance )
95+ {
96+ LogTime ( ) ;
97+ LogStagesCleared ( ) ;
98+ }
99+ } ;
100+
101+ // On player leave
102+ // Currently works when they leave mid-game
103+ // Needs to be used for end of game as well, changed to support each player (will have to retrieve all networkusers)
104+ // NOTE: Ensure that if a player joins and leaves multiple times during a game, their stats aren't multiplied. Maybe cache the stats for each player in the run locally and only upload to the DB when the run ends
105+ On . RoR2 . Networking . GameNetworkManager . OnServerDisconnect += ( orig , run , conn ) =>
106+ {
107+ if ( Run . instance )
108+ {
109+ // Stats
110+ NetworkUser user = FindNetworkUserForConnectionServer ( conn ) ;
111+ GameObject playerMasterObject = user . masterObject ;
112+ StatSheet statSheet ;
113+ PlayerStatsComponent component = playerMasterObject . GetComponent < PlayerStatsComponent > ( ) ;
114+ statSheet = ( ( component != null ) ? component . currentStats : null ) ;
115+ // Print the statsheet to console / log
116+ // Will be changing this to parse and add to the database
117+ // Don't need all the stats they access though, should only use some of the fields (may be able to split up by category)
118+ string [ ] array = new string [ statSheet . fields . Length ] ;
119+ for ( int i = 0 ; i < array . Length ; i ++ )
120+ {
121+ array [ i ] = string . Format ( "[\" {0}\" ]={1}" , statSheet . fields [ i ] . name , statSheet . fields [ i ] . ToString ( ) ) ;
122+ }
123+ Debug . Log ( string . Join ( "\n " , array ) ) ;
124+
125+ LogTime ( ) ;
126+ LogStagesCleared ( ) ;
127+ }
128+ orig ( run , conn ) ;
129+ } ;
130+ }
131+
132+ private static void LogTime ( )
133+ {
134+ if ( ! Run . instance )
135+ {
136+ throw new ConCommandException ( "No run is currently in progress." ) ;
137+ }
138+ Debug . Log ( "Run time is " + Run . instance . GetRunStopwatch ( ) . ToString ( ) ) ;
139+ }
140+
141+ private static void LogStagesCleared ( )
142+ {
143+ if ( ! Run . instance )
144+ {
145+ throw new ConCommandException ( "No run is currently in progress." ) ;
146+ }
147+ Debug . Log ( "Stages cleared: " + Run . instance . NetworkstageClearCount . ToString ( ) ) ;
148+ }
149+
150+ // Borrowed from R2DSEssentials.Util.Networking
151+ private static NetworkUser FindNetworkUserForConnectionServer ( NetworkConnection connection )
152+ {
153+ foreach ( var networkUser in NetworkUser . readOnlyInstancesList )
154+ {
155+ if ( networkUser . connectionToClient == connection )
156+ {
157+ return networkUser ;
158+ }
159+ }
160+
161+ return null ;
162+ }
62163 }
63164}
0 commit comments