Skip to content

Commit

Permalink
SpawnConfigs v0.9.0 - Mono support
Browse files Browse the repository at this point in the history
- Adds mono support (dedicated servers)
- CI integration
  • Loading branch information
data-bomb authored Dec 31, 2023
1 parent c0d13a1 commit f9c159d
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 71 deletions.
119 changes: 80 additions & 39 deletions Si_SpawnConfigs/Si_SpawnConfigs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,26 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#if NET6_0
using Il2Cpp;
#else
using System.Reflection;
#endif

using MelonLoader;
using Si_SpawnConfigs;
using UnityEngine;
using AdminExtension;
using MelonLoader.Utils;
using System.Text.Json;
using static Si_SpawnConfigs.SpawnConfigs;

[assembly: MelonInfo(typeof(SpawnConfigs), "Admin Spawn Configs", "0.8.8", "databomb")]
using System;
using System.Collections.Generic;
using SilicaAdminMod;
using System.Linq;
using System.IO;
using Newtonsoft.Json;

[assembly: MelonInfo(typeof(SpawnConfigs), "Admin Spawn Configs", "0.9.0", "databomb", "https://github.com/data-bomb/Silica")]
[assembly: MelonGame("Bohemia Interactive", "Silica")]
[assembly: MelonOptionalDependencies("Admin Mod")]

namespace Si_SpawnConfigs
{
Expand Down Expand Up @@ -190,7 +199,7 @@ public override void OnLateInitializeMelon()
}
}

public void Command_UndoSpawn(Il2Cpp.Player callerPlayer, String args)
public static void Command_UndoSpawn(Player callerPlayer, String args)
{
// validate argument count
int argumentCount = args.Split(' ').Length - 1;
Expand All @@ -214,7 +223,7 @@ public void Command_UndoSpawn(Il2Cpp.Player callerPlayer, String args)
HelperMethods.AlertAdminAction(callerPlayer, "destroyed last spawned item (" + name + ")");
}

public void Command_Spawn(Il2Cpp.Player callerPlayer, String args)
public static void Command_Spawn(Player callerPlayer, String args)
{
// validate argument count
int argumentCount = args.Split(' ').Length - 1;
Expand All @@ -229,11 +238,11 @@ public void Command_Spawn(Il2Cpp.Player callerPlayer, String args)
return;
}

Vector3 playerPosition = callerPlayer.m_ControlledUnit.WorldPhysicalCenter;
Quaternion playerRotation = callerPlayer.m_ControlledUnit.GetFacingRotation();
Vector3 playerPosition = callerPlayer.ControlledUnit.WorldPhysicalCenter;
Quaternion playerRotation = callerPlayer.ControlledUnit.GetFacingRotation();
String spawnName = args.Split(' ')[1];

int teamIndex = callerPlayer.m_Team.Index;
int teamIndex = callerPlayer.Team.Index;
GameObject? spawnedObject = SpawnAtLocation(spawnName, playerPosition, playerRotation, teamIndex);
if (spawnedObject == null)
{
Expand Down Expand Up @@ -283,17 +292,24 @@ public void Command_Spawn(Il2Cpp.Player callerPlayer, String args)
{
// set team information
BaseGameObject baseObject = spawnedObject.GetBaseGameObject();
if (baseObject.m_Team.Index != teamIndex)
if (baseObject.Team.Index != teamIndex)
{
baseObject.Team = Team.Teams[teamIndex];
baseObject.m_Team = Team.Teams[teamIndex];
//baseObject.m_Team = Team.Teams[teamIndex];
#if NET6_0
baseObject.UpdateToCurrentTeam();
#else
Type baseOjbectType = typeof(BaseGameObject);
MethodInfo updateToCurrentTeamMethod = baseOjbectType.GetMethod("UpdateToCurrentTeam");

updateToCurrentTeamMethod.Invoke(baseObject, null);
#endif
}
}

return spawnedObject;
}
public void Command_SaveSetup(Il2Cpp.Player callerPlayer, String args)
public static void Command_SaveSetup(Player callerPlayer, String args)
{
String commandName = args.Split(' ')[0];

Expand Down Expand Up @@ -360,12 +376,7 @@ public void Command_SaveSetup(Il2Cpp.Player callerPlayer, String args)
SpawnSetup spawnSetup = GenerateSpawnSetup();

// save to file
String JsonRaw = JsonSerializer.Serialize(
spawnSetup,
new JsonSerializerOptions
{
WriteIndented = true
});
String JsonRaw = JsonConvert.SerializeObject(spawnSetup, Newtonsoft.Json.Formatting.Indented);

File.WriteAllText(configFileFullPath, JsonRaw);

Expand All @@ -377,7 +388,7 @@ public void Command_SaveSetup(Il2Cpp.Player callerPlayer, String args)
}
}

public void Command_AddSetup(Il2Cpp.Player callerPlayer, String args)
public static void Command_AddSetup(Player callerPlayer, String args)
{
String commandName = args.Split(' ')[0];

Expand Down Expand Up @@ -430,20 +441,20 @@ public void Command_AddSetup(Il2Cpp.Player callerPlayer, String args)

// check global config options
String JsonRaw = File.ReadAllText(configFileFullPath);
SpawnSetup? spawnSetup = JsonSerializer.Deserialize<SpawnSetup>(JsonRaw);
SpawnSetup? spawnSetup = JsonConvert.DeserializeObject<SpawnSetup>(JsonRaw);
if (spawnSetup == null)
{
HelperMethods.ReplyToCommand(commandName + ": json error in configuration file");
return;
}

if (spawnSetup.Map != null && spawnSetup.Map != NetworkGameServer.GetServerMapName())
if (spawnSetup.Map != null && spawnSetup.Map != NetworkGameServer.GetServerMap())
{
HelperMethods.ReplyToCommand(commandName + ": incompatible map specified");
return;
}

MP_Strategy strategyInstance = GameObject.FindObjectOfType<Il2Cpp.MP_Strategy>();
MP_Strategy strategyInstance = GameObject.FindObjectOfType<MP_Strategy>();
if (spawnSetup.VersusMode != null && spawnSetup.VersusMode != strategyInstance.TeamsVersus.ToString())
{
HelperMethods.ReplyToCommand(commandName + ": incompatible mode specified");
Expand All @@ -464,7 +475,7 @@ public void Command_AddSetup(Il2Cpp.Player callerPlayer, String args)
}
}

public void Command_LoadSetup(Il2Cpp.Player callerPlayer, String args)
public static void Command_LoadSetup(Player callerPlayer, String args)
{
String commandName = args.Split(' ')[0];

Expand Down Expand Up @@ -517,20 +528,20 @@ public void Command_LoadSetup(Il2Cpp.Player callerPlayer, String args)

// check global config options
String JsonRaw = File.ReadAllText(configFileFullPath);
SpawnSetup? spawnSetup = JsonSerializer.Deserialize<SpawnSetup>(JsonRaw);
SpawnSetup? spawnSetup = JsonConvert.DeserializeObject<SpawnSetup>(JsonRaw);
if (spawnSetup == null)
{
HelperMethods.ReplyToCommand(commandName + ": json error in configuration file");
return;
}

if (spawnSetup.Map != null && spawnSetup.Map != NetworkGameServer.GetServerMapName())
if (spawnSetup.Map != null && spawnSetup.Map != NetworkGameServer.GetServerMap())
{
HelperMethods.ReplyToCommand(commandName + ": incompatible map specified");
return;
}

MP_Strategy strategyInstance = GameObject.FindObjectOfType<Il2Cpp.MP_Strategy>();
MP_Strategy strategyInstance = GameObject.FindObjectOfType<MP_Strategy>();
if (spawnSetup.VersusMode != null && spawnSetup.VersusMode != strategyInstance.TeamsVersus.ToString())
{
HelperMethods.ReplyToCommand(commandName + ": incompatible mode specified");
Expand Down Expand Up @@ -653,8 +664,19 @@ public static bool LoadUnits(SpawnSetup addSetup)
{
MelonLogger.Msg("Adding unit " + spawnEntry.Classname);

Vector3 position = new(spawnEntry.Position[0], spawnEntry.Position[1], spawnEntry.Position[2]);
Quaternion rotation = new(spawnEntry.Rotation[0], spawnEntry.Rotation[1], spawnEntry.Rotation[2], spawnEntry.Rotation[3]);
Vector3 position = new Vector3
{
x = spawnEntry.Position[0],
y = spawnEntry.Position[1],
z = spawnEntry.Position[2]
};
Quaternion rotation = new Quaternion
{
x = spawnEntry.Rotation[0],
y = spawnEntry.Rotation[1],
z = spawnEntry.Rotation[2],
w = spawnEntry.Rotation[3]
};
GameObject? spawnedObject = SpawnAtLocation(spawnEntry.Classname, position, rotation, spawnEntry.TeamIndex);
if (spawnedObject == null)
{
Expand Down Expand Up @@ -688,8 +710,19 @@ public static bool LoadStructures(SpawnSetup addSetup)
{
MelonLogger.Msg("Adding structure " + spawnEntry.Classname);

Vector3 position = new(spawnEntry.Position[0], spawnEntry.Position[1], spawnEntry.Position[2]);
Quaternion rotation = new(spawnEntry.Rotation[0], spawnEntry.Rotation[1], spawnEntry.Rotation[2], spawnEntry.Rotation[3]);
Vector3 position = new Vector3
{
x = spawnEntry.Position[0],
y = spawnEntry.Position[1],
z = spawnEntry.Position[2]
};
Quaternion rotation = new Quaternion
{
x = spawnEntry.Rotation[0],
y = spawnEntry.Rotation[1],
z = spawnEntry.Rotation[2],
w = spawnEntry.Rotation[3]
};
GameObject? spawnedObject = SpawnAtLocation(spawnEntry.Classname, position, rotation, spawnEntry.TeamIndex);
if (spawnedObject == null)
{
Expand All @@ -709,7 +742,15 @@ public static bool LoadStructures(SpawnSetup addSetup)
if (thisStructure != null)
{
thisStructure.StructureTechnologyTier = (int)spawnEntry.TechTier;

#if NET6_0
thisStructure.RPC_SynchTechnologyTier();
#else
Type structureType = typeof(Structure);
MethodInfo synchTechMethod = structureType.GetMethod("RPC_SynchTechnologyTier");

synchTechMethod.Invoke(thisStructure, null);
#endif
}
}

Expand All @@ -733,7 +774,7 @@ public static void LoadTeams(SpawnSetup addSetup)
foreach (TeamSpawn spawnEntry in addSetup.Teams)
{
Team.Teams[spawnEntry.TeamIndex].StartingResources = spawnEntry.Resources;
Team.Teams[spawnEntry.TeamIndex].m_StartingResources = spawnEntry.Resources;
//Team.Teams[spawnEntry.TeamIndex].m_StartingResources = spawnEntry.Resources;
}
}
}
Expand All @@ -760,9 +801,9 @@ public static bool ExecuteBatchSpawn(SpawnSetup spawnSetup)
public static SpawnSetup GenerateSpawnSetup(bool includeNetIDs = false)
{
// set global config options
SpawnSetup spawnSetup = new();
spawnSetup.Map = NetworkGameServer.GetServerMapName();
MP_Strategy strategyInstance = GameObject.FindObjectOfType<Il2Cpp.MP_Strategy>();
SpawnSetup spawnSetup = new SpawnSetup();
spawnSetup.Map = NetworkGameServer.GetServerMap();
MP_Strategy strategyInstance = GameObject.FindObjectOfType<MP_Strategy>();
spawnSetup.VersusMode = strategyInstance.TeamsVersus.ToString();

// create a list of all structures and units
Expand All @@ -777,8 +818,8 @@ public static SpawnSetup GenerateSpawnSetup(bool includeNetIDs = false)
continue;
}

TeamSpawn thisTeamSpawn = new();
thisTeamSpawn.Resources = team.m_StartingResources;
TeamSpawn thisTeamSpawn = new TeamSpawn();
thisTeamSpawn.Resources = team.StartingResources;
thisTeamSpawn.TeamIndex = team.Index;
spawnSetup.Teams.Add(thisTeamSpawn);

Expand All @@ -790,7 +831,7 @@ public static SpawnSetup GenerateSpawnSetup(bool includeNetIDs = false)
continue;
}

StructureSpawn thisSpawnEntry = new();
StructureSpawn thisSpawnEntry = new StructureSpawn();

BaseGameObject structureBaseObject = structure.gameObject.GetBaseGameObject();
float[] position = new float[]
Expand Down Expand Up @@ -840,7 +881,7 @@ public static SpawnSetup GenerateSpawnSetup(bool includeNetIDs = false)

foreach (Unit unit in team.Units)
{
UnitSpawn thisSpawnEntry = new();
UnitSpawn thisSpawnEntry = new UnitSpawn();

float[] position = new float[]
{
Expand Down
36 changes: 4 additions & 32 deletions Si_SpawnConfigs/Si_SpawnConfigs.csproj
Original file line number Diff line number Diff line change
@@ -1,42 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<TargetFrameworks>net6.0;netstandard2.1</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<Reference Include="0Harmony">
<HintPath>..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Silica\MelonLoader\net6\0Harmony.dll</HintPath>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Silica\MelonLoader\Il2CppAssemblies\Assembly-CSharp.dll</HintPath>
</Reference>
<Reference Include="Il2CppInterop.Runtime">
<HintPath>..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Silica\MelonLoader\net6\Il2CppInterop.Runtime.dll</HintPath>
</Reference>
<Reference Include="Il2Cppmscorlib">
<HintPath>..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Silica\MelonLoader\Il2CppAssemblies\Il2Cppmscorlib.dll</HintPath>
</Reference>
<Reference Include="MelonLoader">
<HintPath>..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Silica\MelonLoader\net6\MelonLoader.dll</HintPath>
</Reference>
<Reference Include="Si_AdminExtension">
<HintPath>..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Silica\MelonLoader\net6\Si_AdminExtension.dll</HintPath>
</Reference>
<Reference Include="UnityEngine">
<HintPath>..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Silica\MelonLoader\Il2CppAssemblies\UnityEngine.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Silica\MelonLoader\Il2CppAssemblies\UnityEngine.CoreModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.InputLegacyModule">
<HintPath>..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Silica\MelonLoader\Il2CppAssemblies\UnityEngine.InputLegacyModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.PhysicsModule">
<HintPath>..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Silica\MelonLoader\Il2CppAssemblies\UnityEngine.PhysicsModule.dll</HintPath>
</Reference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Silica-MelonLoader-AdminMod" Version="2.0.0" />
<PackageReference Include="Silica-MelonLoader-Dependencies" Version="0.8.19" />
</ItemGroup>

</Project>
25 changes: 25 additions & 0 deletions Si_SpawnConfigs/Si_SpawnConfigs.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.6.33723.286
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Si_SpawnConfigs", "Si_SpawnConfigs.csproj", "{305AE3B9-B67D-4F6B-AC9F-E9F18CC45C5E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{305AE3B9-B67D-4F6B-AC9F-E9F18CC45C5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{305AE3B9-B67D-4F6B-AC9F-E9F18CC45C5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{305AE3B9-B67D-4F6B-AC9F-E9F18CC45C5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{305AE3B9-B67D-4F6B-AC9F-E9F18CC45C5E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {68A72EA6-C4B6-4C2F-BCA8-AAFA066176A8}
EndGlobalSection
EndGlobal

0 comments on commit f9c159d

Please sign in to comment.