@@ -30,6 +30,15 @@ public static bool IsFactionOk(Player player, Actor actor, string faction)
3030 return actor . OccupiesSpace != null ;
3131 }
3232
33+ public static Player ResolvePlayer ( JObject json , World world )
34+ {
35+ var playerId = json ? . TryGetFieldValue ( "__playerId" ) ? . ToString ( ) ;
36+ if ( string . IsNullOrEmpty ( playerId ) )
37+ return world . LocalPlayer ;
38+ var player = world . Players . FirstOrDefault ( p => p . InternalName == playerId ) ;
39+ return player ?? world . LocalPlayer ;
40+ }
41+
3342 public static List < Actor > GetTargets ( JToken targets , World world , Player player )
3443 {
3544 var result = new List < Actor > ( ) ;
@@ -178,7 +187,7 @@ public static CPos GetLocation(JToken location)
178187
179188 public static List < Actor > GetTargetsFromJson ( JObject json , World world , bool bAllowEmpty = false )
180189 {
181- var player = world . LocalPlayer ;
190+ var player = ResolvePlayer ( json , world ) ;
182191 var targets = json . TryGetFieldValue ( "targets" ) ;
183192 if ( targets == null )
184193 {
@@ -246,7 +255,7 @@ public static List<Actor> GetTargetsFromJson(JObject json, World world, bool bAl
246255
247256 public static string SelectUnitCommand ( JObject json , World world )
248257 {
249- var player = world . LocalPlayer ;
258+ var player = ResolvePlayer ( json , world ) ;
250259 var isCombine = json . TryGetFieldValue ( "isCombine" ) ? . ToObject < int > ( ) ;
251260 var actors = GetTargetsFromJson ( json , world ) ;
252261 var newSelection = SelectionUtils . SelectActorsByOwnerAndSelectionClass ( actors , new List < Player > { player } , null ) . ToList ( ) ;
@@ -256,7 +265,7 @@ public static string SelectUnitCommand(JObject json, World world)
256265
257266 public static string FormGroupCommand ( JObject json , World world )
258267 {
259- var player = world . LocalPlayer ;
268+ var player = ResolvePlayer ( json , world ) ;
260269 var groupId = json . TryGetFieldValue ( "groupId" ) ? . ToObject < int > ( ) ;
261270 if ( groupId == null )
262271 {
@@ -273,7 +282,7 @@ public static string FormGroupCommand(JObject json, World world)
273282
274283 public static string MoveActorCommand ( JObject json , World world )
275284 {
276- var player = world . LocalPlayer ;
285+ var player = ResolvePlayer ( json , world ) ;
277286 var actors = GetTargetsFromJson ( json , world ) ;
278287 CPos ? location ;
279288 location = null ;
@@ -383,7 +392,7 @@ public static string MoveActorInPath(IEnumerable<Actor> actors, List<JToken> pat
383392 public static JObject StartProductionCommand ( JObject json , World world )
384393 {
385394 var orders = json . TryGetFieldValue ( "units" ) ? . ToObject < List < JToken > > ( ) ;
386- var player = world . LocalPlayer ;
395+ var player = ResolvePlayer ( json , world ) ;
387396 var ret_str = "" ;
388397 var waitId = - 1 ;
389398 var autoPlace = json . TryGetFieldValue ( "autoPlaceBuilding" ) ? . ToObject < bool > ( ) ?? false ;
@@ -468,7 +477,8 @@ public static string CameraMoveCommand(JObject json, World world)
468477 var direction = json . TryGetFieldValue ( "direction" ) ? . ToObject < string > ( ) ;
469478 var distance = json . TryGetFieldValue ( "distance" ) ? . ToObject < int > ( ) ;
470479 var locationToken = json . TryGetFieldValue ( "location" ) ;
471- var location = GetTargetLocation ( locationToken , world , world . LocalPlayer ) ;
480+ var player = ResolvePlayer ( json , world ) ;
481+ var location = GetTargetLocation ( locationToken , world , player ) ;
472482 if ( ( direction == null || distance == null ) && location == null )
473483 {
474484 return "No direction Or No Distance Or No Location !!!!!!" ;
@@ -521,7 +531,7 @@ public static string CameraMoveCommand(JObject json, World world)
521531
522532 public static string AttackCommand ( JObject json , World world )
523533 {
524- var player = world . LocalPlayer ;
534+ var player = ResolvePlayer ( json , world ) ;
525535 var attacker = GetTargets ( json [ "attackers" ] , world , player ) ;
526536 var target = GetTargetsFromJson ( json , world ) ;
527537
@@ -626,7 +636,7 @@ public static string ViewCommand(JObject json, World world)
626636
627637 public static string OccupyCommand ( JObject json , World world )
628638 {
629- var player = world . LocalPlayer ;
639+ var player = ResolvePlayer ( json , world ) ;
630640 var actors = GetTargets ( json [ "occupiers" ] , world , player ) ;
631641 var targets = GetTargets ( json [ "targets" ] , world , player ) ;
632642
@@ -674,7 +684,7 @@ public static string OccupyCommand(JObject json, World world)
674684 public static string RepairCommand ( JObject json , World world )
675685 {
676686 var actors = GetTargetsFromJson ( json , world ) ;
677- var player = world . LocalPlayer ;
687+ var player = ResolvePlayer ( json , world ) ;
678688 foreach ( var a in actors )
679689 {
680690 if ( a . Info . HasTraitInfo < RepairableBuildingInfo > ( ) )
@@ -742,7 +752,7 @@ public static string StopCommand(JObject json, World world)
742752
743753 public static string SetRallyPointCommand ( JObject json , World world )
744754 {
745- var player = world . LocalPlayer ;
755+ var player = ResolvePlayer ( json , world ) ;
746756 var actors = GetTargetsFromJson ( json , world ) ;
747757 var retstr = "" ;
748758 var locationToken = json . TryGetFieldValue ( "location" ) ;
@@ -786,7 +796,7 @@ public static string SetRallyPointCommand(JObject json, World world)
786796
787797 public static string ManageProductionCommand ( JObject json , World world )
788798 {
789- var player = world . LocalPlayer ;
799+ var player = ResolvePlayer ( json , world ) ;
790800
791801 // 获取队列类型
792802 var queueType = json . TryGetFieldValue ( "queueType" ) ? . ToString ( ) ;
@@ -875,7 +885,7 @@ public static string ManageProductionCommand(JObject json, World world)
875885
876886 public static string PlaceBuildingCommand ( JObject json , World world )
877887 {
878- var player = world . LocalPlayer ;
888+ var player = ResolvePlayer ( json , world ) ;
879889
880890 // 获取队列类型
881891 var queueType = json . TryGetFieldValue ( "queueType" ) ? . ToString ( ) ;
@@ -1052,7 +1062,7 @@ public static IEnumerable<JObject> QueryFrozenActors(JToken targets, World world
10521062
10531063 public static JObject ActorQueryCommand ( JObject json , World world )
10541064 {
1055- var player = world . LocalPlayer ;
1065+ var player = ResolvePlayer ( json , world ) ;
10561066 var targets = json . TryGetFieldValue ( "targets" ) ;
10571067 List < Actor > targetActors ;
10581068 if ( targets == null )
@@ -1138,7 +1148,7 @@ public static JObject WaitQueryCommand(JObject json, World world)
11381148 public static JObject QueryCanProduceCommand ( JObject json , World world )
11391149 {
11401150 var orders = json . TryGetFieldValue ( "units" ) ? . ToObject < List < JToken > > ( ) ;
1141- var player = world . LocalPlayer ;
1151+ var player = ResolvePlayer ( json , world ) ;
11421152 var ret_str = "" ;
11431153 var canProduce = false ;
11441154
@@ -1202,6 +1212,7 @@ public static JObject QueryCanProduceCommand(JObject json, World world)
12021212
12031213 public static JObject FogQueryCommand ( JObject json , World world )
12041214 {
1215+ var player = ResolvePlayer ( json , world ) ;
12051216 var jpos = json . TryGetFieldValue ( "pos" ) ;
12061217 if ( jpos == null )
12071218 {
@@ -1212,14 +1223,15 @@ public static JObject FogQueryCommand(JObject json, World world)
12121223
12131224 var result = new JObject
12141225 {
1215- [ "IsVisible" ] = world . FogObscures ( pos ) ,
1216- [ "IsExplored" ] = world . ShroudObscures ( pos )
1226+ [ "IsVisible" ] = player . Shroud . IsVisible ( pos ) ,
1227+ [ "IsExplored" ] = player . Shroud . IsExplored ( pos )
12171228 } ;
12181229 return result ;
12191230 }
12201231
12211232 public static JObject MapQueryCommand ( JObject json , World world )
12221233 {
1234+ var player = ResolvePlayer ( json , world ) ;
12231235 var map = world . Map ;
12241236 var width = map . MapSize . X - 2 ;
12251237 var height = map . MapSize . Y - 2 ;
@@ -1245,8 +1257,8 @@ public static JObject MapQueryCommand(JObject json, World world)
12451257 {
12461258 var pos = new CPos ( x , y ) ;
12471259 heightRow . Add ( map . Height [ pos ] ) ;
1248- isVisibleRow . Add ( ! world . FogObscures ( pos ) ) ;
1249- isExploredRow . Add ( ! world . ShroudObscures ( pos ) ) ;
1260+ isVisibleRow . Add ( player . Shroud . IsVisible ( pos ) ) ;
1261+ isExploredRow . Add ( player . Shroud . IsExplored ( pos ) ) ;
12501262 terrainRow . Add ( map . Tiles [ pos ] . Type ) ;
12511263 resourcesTypeRow . Add ( map . Resources [ pos ] . Type ) ;
12521264 resourcesRow . Add ( map . Resources [ pos ] . Index ) ;
@@ -1260,6 +1272,34 @@ public static JObject MapQueryCommand(JObject json, World world)
12601272 resourcesArray . Add ( resourcesRow ) ;
12611273 }
12621274
1275+ // Resource spawner actors (MINE/GMINE)
1276+ var resourceActors = new JArray (
1277+ world . ActorsHavingTrait < SeedsResource > ( )
1278+ . Where ( a => a . IsInWorld && ! a . IsDead )
1279+ . Select ( a => new JObject
1280+ {
1281+ [ "type" ] = a . Info . Name ,
1282+ [ "displayName" ] = CopilotsConfig . GetChineseByConfigName ( a . Info . Name ) ,
1283+ [ "resourceType" ] = a . Info . TraitInfo < SeedsResourceInfo > ( ) . ResourceType ,
1284+ [ "x" ] = a . Location . X ,
1285+ [ "y" ] = a . Location . Y
1286+ } ) . ToArray ( )
1287+ ) ;
1288+
1289+ // Oil wells / cash trickler buildings
1290+ var oilWells = new JArray (
1291+ world . ActorsHavingTrait < CashTrickler > ( )
1292+ . Where ( a => a . IsInWorld && ! a . IsDead )
1293+ . Select ( a => new JObject
1294+ {
1295+ [ "type" ] = a . Info . Name ,
1296+ [ "displayName" ] = CopilotsConfig . GetChineseByConfigName ( a . Info . Name ) ,
1297+ [ "owner" ] = a . Owner ? . InternalName ?? "Neutral" ,
1298+ [ "x" ] = a . Location . X ,
1299+ [ "y" ] = a . Location . Y
1300+ } ) . ToArray ( )
1301+ ) ;
1302+
12631303 var result = new JObject
12641304 {
12651305 [ "MapWidth" ] = width ,
@@ -1269,7 +1309,9 @@ public static JObject MapQueryCommand(JObject json, World world)
12691309 [ "IsExplored" ] = isExploredArray ,
12701310 [ "Terrain" ] = terrainArray ,
12711311 [ "ResourcesType" ] = resourcesTypeArray ,
1272- [ "Resources" ] = resourcesArray
1312+ [ "Resources" ] = resourcesArray ,
1313+ [ "resourceActors" ] = resourceActors ,
1314+ [ "oilWells" ] = oilWells
12731315 } ;
12741316
12751317 return result ;
@@ -1322,7 +1364,7 @@ public static JObject PingCommand(JObject json, World world)
13221364
13231365 public static JObject PlayerBaseInfoQueryCommand ( JObject json , World world )
13241366 {
1325- var player = world . LocalPlayer ;
1367+ var player = ResolvePlayer ( json , world ) ;
13261368 var playerRes = player . PlayerActor . Trait < PlayerResources > ( ) ;
13271369 var powerManager = player . PlayerActor . Trait < PowerManager > ( ) ;
13281370 if ( playerRes == null || powerManager == null )
@@ -1378,7 +1420,7 @@ public static JObject ScreenInfoQueryCommand(JObject json, World world)
13781420
13791421 public static JObject QueryProductionQueueCommand ( JObject json , World world )
13801422 {
1381- var player = world . LocalPlayer ;
1423+ var player = ResolvePlayer ( json , world ) ;
13821424
13831425 // 获取队列类型
13841426 var queueType = json . TryGetFieldValue ( "queueType" ) ? . ToString ( ) ;
@@ -1465,7 +1507,7 @@ public static JObject QueryMatchInfoCommand(JObject json, World world)
14651507 var scoreService = world . WorldActor . TraitOrDefault < CopilotScoreService > ( ) ;
14661508 if ( scoreService == null )
14671509 throw new ArgumentException ( "ScoreService or ControlPoint manager not found" ) ;
1468- var player = world . LocalPlayer ;
1510+ var player = ResolvePlayer ( json , world ) ;
14691511 var enemyPlayer = world . Players . FirstOrDefault ( p => p != player && ! p . NonCombatant ) ;
14701512 var remainingTime = scoreService . RemainingTime ;
14711513 if ( remainingTime < 0 ) remainingTime = 0 ;
@@ -1481,6 +1523,28 @@ public static JObject QueryMatchInfoCommand(JObject json, World world)
14811523 }
14821524
14831525
1526+ public static JObject QueryPlayersCommand ( JObject json , World world )
1527+ {
1528+ var players = world . Players
1529+ . Where ( p => ! p . NonCombatant )
1530+ . Select ( p => new JObject
1531+ {
1532+ [ "internalName" ] = p . InternalName ,
1533+ [ "clientIndex" ] = p . ClientIndex ,
1534+ [ "faction" ] = p . Faction . InternalName ,
1535+ [ "isBot" ] = p . IsBot ,
1536+ [ "team" ] = p . PlayerReference . Team ,
1537+ [ "color" ] = p . Color . ToString ( ) ,
1538+ [ "isLocalPlayer" ] = p == world . LocalPlayer
1539+ } ) . ToArray ( ) ;
1540+
1541+ var result = new JObject
1542+ {
1543+ [ "players" ] = new JArray ( players )
1544+ } ;
1545+ return result ;
1546+ }
1547+
14841548 public void WorldLoaded ( World w , WorldRenderer wr )
14851549 {
14861550 if ( w . Type == WorldType . Regular && w . CopilotServer != null )
@@ -1514,6 +1578,7 @@ public void WorldLoaded(World w, WorldRenderer wr)
15141578 w . CopilotServer . QueryHandlers [ "player_baseinfo_query" ] = PlayerBaseInfoQueryCommand ;
15151579 w . CopilotServer . QueryHandlers [ "screen_info_query" ] = ScreenInfoQueryCommand ;
15161580 w . CopilotServer . QueryHandlers [ "ping" ] = PingCommand ;
1581+ w . CopilotServer . QueryHandlers [ "query_players" ] = QueryPlayersCommand ;
15171582
15181583 CopilotsConfig . LoadConfig ( ) ;
15191584 CopilotsUtils . WaitInit ( ) ;
0 commit comments