Publictest (#335)

* Fix compiler errors

* Fix Jenkins

* Build public test as Release

* Fix more things

* Oops

* Remove obsolete code

* Fix GameStatePatchShim
This commit is contained in:
Brant Martin
2019-08-22 13:25:53 -04:00
committed by GitHub
parent 1a1f8b2235
commit 43adecaf99
22 changed files with 68 additions and 769 deletions

View File

@@ -1,6 +1,6 @@
pushd pushd
$steamData = "C:/Steam/Data/" $steamData = "C:/Steam/Data-playtest/"
$steamCMDPath = "C:/Steam/steamcmd/" $steamCMDPath = "C:/Steam/steamcmd/"
$steamCMDZip = "C:/Steam/steamcmd.zip" $steamCMDZip = "C:/Steam/steamcmd.zip"
@@ -17,6 +17,6 @@ if (!(Test-Path $steamCMDPath)) {
} }
cd "$steamData" cd "$steamData"
& "$steamCMDPath/steamcmd.exe" "+login anonymous" "+force_install_dir $steamData" "+app_update 298740" "+quit" & "$steamCMDPath/steamcmd.exe" "+login anonymous" "+force_install_dir $steamData" "+app_update 298740 -beta publictest -betapassword nt8WuDw9kdvE validate" "+quit"
popd popd

4
Jenkinsfile vendored
View File

@@ -22,7 +22,7 @@ node {
stage('Acquire SE') { stage('Acquire SE') {
bat 'powershell -File Jenkins/jenkins-grab-se.ps1' bat 'powershell -File Jenkins/jenkins-grab-se.ps1'
bat 'IF EXIST GameBinaries RMDIR GameBinaries' bat 'IF EXIST GameBinaries RMDIR GameBinaries'
bat 'mklink /J GameBinaries "C:/Steam/Data/DedicatedServer64/"' bat 'mklink /J GameBinaries "C:/Steam/Data-playtest/DedicatedServer64/"'
} }
stage('Acquire NuGet Packages') { stage('Acquire NuGet Packages') {
@@ -31,7 +31,7 @@ node {
stage('Build') { stage('Build') {
currentBuild.description = bat(returnStdout: true, script: '@powershell -File Versioning/version.ps1').trim() currentBuild.description = bat(returnStdout: true, script: '@powershell -File Versioning/version.ps1').trim()
if (env.BRANCH_NAME == "master" || env.BRANCH_NAME == "Patron") { if (env.BRANCH_NAME == "master" || env.BRANCH_NAME == "Patron" || env.BRANCH_NAME == "publictest") {
buildMode = "Release" buildMode = "Release"
} else { } else {
buildMode = "Debug" buildMode = "Debug"

View File

@@ -30,9 +30,6 @@ namespace Torch.API.WebAPI
public async Task<Job> GetLatestVersion(string branch) public async Task<Job> GetLatestVersion(string branch)
{ {
#if DEBUG
branch = "master";
#endif
var h = await _client.GetAsync(string.Format(BRANCH_QUERY, branch)); var h = await _client.GetAsync(string.Format(BRANCH_QUERY, branch));
if (!h.IsSuccessStatusCode) if (!h.IsSuccessStatusCode)
{ {

View File

@@ -31,7 +31,7 @@ namespace Torch.Server
private const string RUNSCRIPT = @"force_install_dir ../ private const string RUNSCRIPT = @"force_install_dir ../
login anonymous login anonymous
app_update 298740 app_update 298740 -beta publictest -betapassword nt8WuDw9kdvE validate
quit"; quit";
private TorchConfig _config; private TorchConfig _config;

View File

@@ -198,16 +198,6 @@ namespace Torch.Server.Managers
public void SaveConfig() public void SaveConfig()
{ {
var cf = Torch.Config as TorchConfig;
if (cf?.ReservedPlayers?.Count > 0)
{
foreach (var res in cf.ReservedPlayers)
{
if (!DedicatedConfig.Reserved.Contains(res))
DedicatedConfig.Reserved.Add(res);
}
}
DedicatedConfig.Save(Path.Combine(Torch.Config.InstancePath, CONFIG_NAME)); DedicatedConfig.Save(Path.Combine(Torch.Config.InstancePath, CONFIG_NAME));
Log.Info("Saved dedicated config."); Log.Info("Saved dedicated config.");

View File

@@ -0,0 +1,48 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using NLog;
using Sandbox;
using Torch.Managers.PatchManager;
using Torch.Managers.PatchManager.MSIL;
namespace Torch.Patches
{
/// <summary>
/// Patches MySandboxGame.InitQuickLaunch to rethrow exceptions caught during session load.
/// </summary>
[PatchShim]
public static class WorldLoadExceptionPatch
{
private static readonly ILogger _log = LogManager.GetCurrentClassLogger();
public static void Patch(PatchContext ctx)
{
ctx.GetPattern(typeof(MySandboxGame).GetMethod("InitQuickLaunch", BindingFlags.Instance | BindingFlags.NonPublic))
.Transpilers.Add(typeof(WorldLoadExceptionPatch).GetMethod(nameof(Transpile), BindingFlags.Static | BindingFlags.NonPublic));
}
private static IEnumerable<MsilInstruction> Transpile(IEnumerable<MsilInstruction> method)
{
var msil = method.ToList();
for (var i = 0; i < msil.Count; i++)
{
if (msil[i].TryCatchOperations.All(x => x.Type != MsilTryCatchOperationType.BeginClauseBlock))
continue;
for (; i < msil.Count; i++)
{
if (msil[i].OpCode != OpCodes.Leave)
continue;
msil[i] = new MsilInstruction(OpCodes.Rethrow);
break;
}
}
return msil;
}
}
}

View File

@@ -208,15 +208,8 @@
<HintPath>..\GameBinaries\VRage.Math.dll</HintPath> <HintPath>..\GameBinaries\VRage.Math.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="VRage.Native, Version=0.0.0.0, Culture=neutral, processorArchitecture=AMD64"> <Reference Include="VRage.Platform.Windows, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<SpecificVersion>False</SpecificVersion> <HintPath>..\GameBinaries\VRage.Platform.Windows.dll</HintPath>
<HintPath>..\GameBinaries\VRage.Native.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="VRage.OpenVRWrapper, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\GameBinaries\VRage.OpenVRWrapper.dll</HintPath>
<Private>False</Private>
</Reference> </Reference>
<Reference Include="VRage.Render, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="VRage.Render, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
@@ -257,6 +250,7 @@
<Compile Include="NativeMethods.cs" /> <Compile Include="NativeMethods.cs" />
<Compile Include="Initializer.cs" /> <Compile Include="Initializer.cs" />
<Compile Include="Patches\PromotePatch.cs" /> <Compile Include="Patches\PromotePatch.cs" />
<Compile Include="Patches\WorldLoadExceptionPatch.cs" />
<Compile Include="Properties\Annotations.cs" /> <Compile Include="Properties\Annotations.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TorchConfig.cs" /> <Compile Include="TorchConfig.cs" />

View File

@@ -109,10 +109,6 @@ namespace Torch.Server
public string LastUsedTheme { get; set; } = "Torch Theme"; public string LastUsedTheme { get; set; } = "Torch Theme";
//TODO: REMOVE ME BY JULY 2019
[Obsolete("Use vanilla reserved slot config")]
public HashSet<ulong> ReservedPlayers { get; set; } = new HashSet<ulong>();
//Prevent reserved players being written to disk, but allow it to be read //Prevent reserved players being written to disk, but allow it to be read
//remove this when ReservedPlayers is removed //remove this when ReservedPlayers is removed
private bool ShouldSerializeReservedPlayers() => false; private bool ShouldSerializeReservedPlayers() => false;

View File

@@ -27,6 +27,7 @@ using VRage;
using VRage.Dedicated; using VRage.Dedicated;
using VRage.Dedicated.RemoteAPI; using VRage.Dedicated.RemoteAPI;
using VRage.GameServices; using VRage.GameServices;
using VRage.Scripting;
using VRage.Steam; using VRage.Steam;
using Timer = System.Threading.Timer; using Timer = System.Threading.Timer;

View File

@@ -1,254 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using VRage;
using VRage.Library.Collections;
using VRage.Network;
using VRage.Serialization;
namespace Torch.Managers
{
[Obsolete("The entire network intercept system is deprecated. Please use method patches instead.")]
public abstract class NetworkHandlerBase
{
/// <summary>
/// Check the method name and do unit tests on parameters in here.
/// </summary>
/// <param name="site"></param>
/// <returns></returns>
[Obsolete("The entire network intercept system is deprecated. Please use method patches instead.")]
public abstract bool CanHandle(CallSite site);
/// <summary>
/// Performs action on network packet. Return value of true means the packet has been handled, and will not be passed on to the game server.
/// </summary>
/// <param name="remoteUserId"></param>
/// <param name="site"></param>
/// <param name="stream"></param>
/// <param name="obj"></param>
/// <param name="packet"></param>
/// <returns></returns>
[Obsolete("The entire network intercept system is deprecated. Please use method patches instead.")]
public abstract bool Handle(ulong remoteUserId, CallSite site, BitStream stream, object obj, MyPacket packet);
/// <summary>
/// Extracts method arguments from the bitstream or packs them back in, depending on stream read mode.
/// </summary>
/// <typeparam name="T1"></typeparam>
/// <param name="info"></param>
/// <param name="stream"></param>
/// <param name="arg1"></param>
[Obsolete("The entire network intercept system is deprecated. Please use method patches instead.")]
public void Serialize<T1>(MethodInfo info, BitStream stream, ref T1 arg1)
{
var s1 = MyFactory.GetSerializer<T1>();
var args = info.GetParameters();
var info1 = MySerializeInfo.CreateForParameter(args, 0);
if (stream.Reading)
{
MySerializationHelpers.CreateAndRead(stream, out arg1, s1, info1);
}
else
{
MySerializationHelpers.Write(stream, ref arg1, s1, info1);
}
}
[Obsolete("The entire network intercept system is deprecated. Please use method patches instead.")]
public void Serialize<T1, T2>(MethodInfo info, BitStream stream, ref T1 arg1, ref T2 arg2)
{
var s1 = MyFactory.GetSerializer<T1>();
var s2 = MyFactory.GetSerializer<T2>();
var args = info.GetParameters();
var info1 = MySerializeInfo.CreateForParameter(args, 0);
var info2 = MySerializeInfo.CreateForParameter(args, 1);
if (stream.Reading)
{
MySerializationHelpers.CreateAndRead(stream, out arg1, s1, info1);
MySerializationHelpers.CreateAndRead(stream, out arg2, s2, info2);
}
else
{
MySerializationHelpers.Write(stream, ref arg1, s1, info1);
MySerializationHelpers.Write(stream, ref arg2, s2, info2);
}
}
[Obsolete("The entire network intercept system is deprecated. Please use method patches instead.")]
public void Serialize<T1, T2, T3>(MethodInfo info, BitStream stream, ref T1 arg1, ref T2 arg2, ref T3 arg3)
{
var s1 = MyFactory.GetSerializer<T1>();
var s2 = MyFactory.GetSerializer<T2>();
var s3 = MyFactory.GetSerializer<T3>();
var args = info.GetParameters();
var info1 = MySerializeInfo.CreateForParameter(args, 0);
var info2 = MySerializeInfo.CreateForParameter(args, 1);
var info3 = MySerializeInfo.CreateForParameter(args, 2);
if (stream.Reading)
{
MySerializationHelpers.CreateAndRead(stream, out arg1, s1, info1);
MySerializationHelpers.CreateAndRead(stream, out arg2, s2, info2);
MySerializationHelpers.CreateAndRead(stream, out arg3, s3, info3);
}
else
{
MySerializationHelpers.Write(stream, ref arg1, s1, info1);
MySerializationHelpers.Write(stream, ref arg2, s2, info2);
MySerializationHelpers.Write(stream, ref arg3, s3, info3);
}
}
[Obsolete("The entire network intercept system is deprecated. Please use method patches instead.")]
public void Serialize<T1, T2, T3, T4>(MethodInfo info, BitStream stream, ref T1 arg1, ref T2 arg2, ref T3 arg3, ref T4 arg4)
{
var s1 = MyFactory.GetSerializer<T1>();
var s2 = MyFactory.GetSerializer<T2>();
var s3 = MyFactory.GetSerializer<T3>();
var s4 = MyFactory.GetSerializer<T4>();
var args = info.GetParameters();
var info1 = MySerializeInfo.CreateForParameter(args, 0);
var info2 = MySerializeInfo.CreateForParameter(args, 1);
var info3 = MySerializeInfo.CreateForParameter(args, 2);
var info4 = MySerializeInfo.CreateForParameter(args, 3);
if (stream.Reading)
{
MySerializationHelpers.CreateAndRead(stream, out arg1, s1, info1);
MySerializationHelpers.CreateAndRead(stream, out arg2, s2, info2);
MySerializationHelpers.CreateAndRead(stream, out arg3, s3, info3);
MySerializationHelpers.CreateAndRead(stream, out arg4, s4, info4);
}
else
{
MySerializationHelpers.Write(stream, ref arg1, s1, info1);
MySerializationHelpers.Write(stream, ref arg2, s2, info2);
MySerializationHelpers.Write(stream, ref arg3, s3, info3);
MySerializationHelpers.Write(stream, ref arg4, s4, info4);
}
}
[Obsolete("The entire network intercept system is deprecated. Please use method patches instead.")]
public void Serialize<T1, T2, T3, T4, T5>(MethodInfo info, BitStream stream, ref T1 arg1, ref T2 arg2, ref T3 arg3, ref T4 arg4, ref T5 arg5)
{
var s1 = MyFactory.GetSerializer<T1>();
var s2 = MyFactory.GetSerializer<T2>();
var s3 = MyFactory.GetSerializer<T3>();
var s4 = MyFactory.GetSerializer<T4>();
var s5 = MyFactory.GetSerializer<T5>();
var args = info.GetParameters();
var info1 = MySerializeInfo.CreateForParameter(args, 0);
var info2 = MySerializeInfo.CreateForParameter(args, 1);
var info3 = MySerializeInfo.CreateForParameter(args, 2);
var info4 = MySerializeInfo.CreateForParameter(args, 3);
var info5 = MySerializeInfo.CreateForParameter(args, 4);
if (stream.Reading)
{
MySerializationHelpers.CreateAndRead(stream, out arg1, s1, info1);
MySerializationHelpers.CreateAndRead(stream, out arg2, s2, info2);
MySerializationHelpers.CreateAndRead(stream, out arg3, s3, info3);
MySerializationHelpers.CreateAndRead(stream, out arg4, s4, info4);
MySerializationHelpers.CreateAndRead(stream, out arg5, s5, info5);
}
else
{
MySerializationHelpers.Write(stream, ref arg1, s1, info1);
MySerializationHelpers.Write(stream, ref arg2, s2, info2);
MySerializationHelpers.Write(stream, ref arg3, s3, info3);
MySerializationHelpers.Write(stream, ref arg4, s4, info4);
MySerializationHelpers.Write(stream, ref arg5, s5, info5);
}
}
[Obsolete("The entire network intercept system is deprecated. Please use method patches instead.")]
public void Serialize<T1, T2, T3, T4, T5, T6>(MethodInfo info, BitStream stream, ref T1 arg1, ref T2 arg2, ref T3 arg3, ref T4 arg4, ref T5 arg5, ref T6 arg6)
{
var s1 = MyFactory.GetSerializer<T1>();
var s2 = MyFactory.GetSerializer<T2>();
var s3 = MyFactory.GetSerializer<T3>();
var s4 = MyFactory.GetSerializer<T4>();
var s5 = MyFactory.GetSerializer<T5>();
var s6 = MyFactory.GetSerializer<T6>();
var args = info.GetParameters();
var info1 = MySerializeInfo.CreateForParameter(args, 0);
var info2 = MySerializeInfo.CreateForParameter(args, 1);
var info3 = MySerializeInfo.CreateForParameter(args, 2);
var info4 = MySerializeInfo.CreateForParameter(args, 3);
var info5 = MySerializeInfo.CreateForParameter(args, 4);
var info6 = MySerializeInfo.CreateForParameter(args, 5);
if (stream.Reading)
{
MySerializationHelpers.CreateAndRead(stream, out arg1, s1, info1);
MySerializationHelpers.CreateAndRead(stream, out arg2, s2, info2);
MySerializationHelpers.CreateAndRead(stream, out arg3, s3, info3);
MySerializationHelpers.CreateAndRead(stream, out arg4, s4, info4);
MySerializationHelpers.CreateAndRead(stream, out arg5, s5, info5);
MySerializationHelpers.CreateAndRead(stream, out arg6, s6, info6);
}
else
{
MySerializationHelpers.Write(stream, ref arg1, s1, info1);
MySerializationHelpers.Write(stream, ref arg2, s2, info2);
MySerializationHelpers.Write(stream, ref arg3, s3, info3);
MySerializationHelpers.Write(stream, ref arg4, s4, info4);
MySerializationHelpers.Write(stream, ref arg5, s5, info5);
MySerializationHelpers.Write(stream, ref arg6, s6, info6);
}
}
[Obsolete("The entire network intercept system is deprecated. Please use method patches instead.")]
public void Serialize<T1, T2, T3, T4, T5, T6, T7>(MethodInfo info, BitStream stream, ref T1 arg1, ref T2 arg2, ref T3 arg3, ref T4 arg4, ref T5 arg5, ref T6 arg6, ref T7 arg7)
{
var s1 = MyFactory.GetSerializer<T1>();
var s2 = MyFactory.GetSerializer<T2>();
var s3 = MyFactory.GetSerializer<T3>();
var s4 = MyFactory.GetSerializer<T4>();
var s5 = MyFactory.GetSerializer<T5>();
var s6 = MyFactory.GetSerializer<T6>();
var s7 = MyFactory.GetSerializer<T7>();
var args = info.GetParameters();
var info1 = MySerializeInfo.CreateForParameter(args, 0);
var info2 = MySerializeInfo.CreateForParameter(args, 1);
var info3 = MySerializeInfo.CreateForParameter(args, 2);
var info4 = MySerializeInfo.CreateForParameter(args, 3);
var info5 = MySerializeInfo.CreateForParameter(args, 4);
var info6 = MySerializeInfo.CreateForParameter(args, 5);
var info7 = MySerializeInfo.CreateForParameter(args, 6);
if ( stream.Reading )
{
MySerializationHelpers.CreateAndRead(stream, out arg1, s1, info1);
MySerializationHelpers.CreateAndRead(stream, out arg2, s2, info2);
MySerializationHelpers.CreateAndRead(stream, out arg3, s3, info3);
MySerializationHelpers.CreateAndRead(stream, out arg4, s4, info4);
MySerializationHelpers.CreateAndRead(stream, out arg5, s5, info5);
MySerializationHelpers.CreateAndRead(stream, out arg6, s6, info6);
MySerializationHelpers.CreateAndRead(stream, out arg7, s7, info7);
}
else
{
MySerializationHelpers.Write(stream, ref arg1, s1, info1);
MySerializationHelpers.Write(stream, ref arg2, s2, info2);
MySerializationHelpers.Write(stream, ref arg3, s3, info3);
MySerializationHelpers.Write(stream, ref arg4, s4, info4);
MySerializationHelpers.Write(stream, ref arg5, s5, info5);
MySerializationHelpers.Write(stream, ref arg6, s6, info6);
MySerializationHelpers.Write(stream, ref arg7, s7, info7);
}
}
}
}

View File

@@ -10,16 +10,10 @@ using VRageMath;
namespace Torch.Managers namespace Torch.Managers
{ {
//TOOD: Make this not a manager, and instead just a static class? public static class NetworkManager
public partial class NetworkManager : Manager, INetworkManager
{ {
private static Logger _log = LogManager.GetCurrentClassLogger(); private static Logger _log = LogManager.GetCurrentClassLogger();
public NetworkManager(ITorchBase torchInstance) : base(torchInstance)
{
}
#region Network Injection #region Network Injection
private static Dictionary<MethodInfo, Delegate> _delegateCache = new Dictionary<MethodInfo, Delegate>(); private static Dictionary<MethodInfo, Delegate> _delegateCache = new Dictionary<MethodInfo, Delegate>();

View File

@@ -1,407 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Sandbox.Engine.Multiplayer;
using Sandbox.Game.Multiplayer;
using Torch.API.Managers;
using Torch.Utils;
using VRage;
using VRage.Library.Collections;
using VRage.Network;
using VRageMath;
namespace Torch.Managers
{
//Everything in this file is deprecated and should be deleted Eventually(tm)
public partial class NetworkManager
{
[ReflectedGetter(Name = "m_methodInfoLookup")]
private static Func<MyEventTable, Dictionary<MethodInfo, CallSite>> _methodInfoLookupGetter;
private const int MAX_ARGUMENT = 6;
private const int GENERIC_PARAMETERS = 8;
private const int DISPATCH_PARAMETERS = 11;
private static readonly DBNull DbNull = DBNull.Value;
private static MethodInfo _dispatchInfo;
private static MethodInfo DispatchEventInfo => _dispatchInfo ?? (_dispatchInfo = typeof(MyReplicationLayerBase).GetMethod("DispatchEvent", BindingFlags.NonPublic | BindingFlags.Instance));
private const string _myTransportLayerField = "TransportLayer";
private const string _transportHandlersField = "m_handlers";
private readonly HashSet<INetworkHandler> _networkHandlers = new HashSet<INetworkHandler>();
private bool _init;
[ReflectedGetter(Name = "m_typeTable")]
private static Func<MyReplicationLayerBase, MyTypeTable> _typeTableGetter;
[ReflectedMethod(Type = typeof(MyReplicationLayer), Name = "GetObjectByNetworkId")]
private static Func<MyReplicationLayer, NetworkId, IMyNetObject> _getObjectByNetworkId;
private static bool ReflectionUnitTest(bool suppress = false)
{
try
{
var syncLayerType = typeof(MySyncLayer);
var transportLayerField = syncLayerType.GetField(_myTransportLayerField, BindingFlags.NonPublic | BindingFlags.Instance);
if (transportLayerField == null)
throw new TypeLoadException("Could not find internal type for TransportLayer");
var transportLayerType = transportLayerField.FieldType;
if (!Reflection.HasField(transportLayerType, _transportHandlersField))
throw new TypeLoadException("Could not find Handlers field");
return true;
}
catch (TypeLoadException ex)
{
_log.Error(ex);
if (suppress)
return false;
throw;
}
}
/// <inheritdoc/>
public override void Attach()
{
//disable all this for now
_log.Warn("Network intercept disabled. Some plugins may not work correctly.");
return;
if (_init)
return;
_init = true;
if (!ReflectionUnitTest())
throw new InvalidOperationException("Reflection unit test failed.");
//don't bother with nullchecks here, it was all handled in ReflectionUnitTest
var transportType = typeof(MySyncLayer).GetField(_myTransportLayerField, BindingFlags.NonPublic | BindingFlags.Instance).FieldType;
var transportInstance = typeof(MySyncLayer).GetField(_myTransportLayerField, BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(MyMultiplayer.Static.SyncLayer);
var handlers = (IDictionary)transportType.GetField(_transportHandlersField, BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(transportInstance);
var handlerTypeField = handlers.GetType().GenericTypeArguments[0].GetField("messageId"); //Should be MyTransportLayer.HandlerId
object id = null;
foreach (var key in handlers.Keys)
{
if ((MyMessageId)handlerTypeField.GetValue(key) != MyMessageId.RPC)
continue;
id = key;
break;
}
if (id == null)
throw new InvalidOperationException("RPC handler not found.");
//remove Keen's network listener
handlers.Remove(id);
//replace it with our own
handlers.Add(id, new Action<MyPacket>(OnEvent));
//PrintDebug();
_log.Debug("Initialized network intercept");
}
/// <inheritdoc/>
public override void Detach()
{
// TODO reverse what was done in Attach
}
#region Network Injection
/// <summary>
/// Broadcasts an event to all connected clients
/// </summary>
/// <param name="method"></param>
/// <param name="obj"></param>
/// <param name="args"></param>
[Obsolete("Old injection system deprecated. Use the generic methods instead.")]
public void RaiseEvent(MethodInfo method, object obj, params object[] args)
{
//default(EndpointId) tells the network to broadcast the message
RaiseEvent(method, obj, default(EndpointId), args);
}
/// <summary>
/// Sends an event to one client by SteamId
/// </summary>
/// <param name="method"></param>
/// <param name="obj"></param>
/// <param name="steamId"></param>
/// <param name="args"></param>
[Obsolete("Old injection system deprecated. Use the generic methods instead.")]
public void RaiseEvent(MethodInfo method, object obj, ulong steamId, params object[] args)
{
RaiseEvent(method, obj, new EndpointId(steamId), args);
}
/// <summary>
/// Sends an event to one client
/// </summary>
/// <param name="method"></param>
/// <param name="obj"></param>
/// <param name="endpoint"></param>
/// <param name="args"></param>
[Obsolete("Old injection system deprecated. Use the generic methods instead.")]
public void RaiseEvent(MethodInfo method, object obj, EndpointId endpoint, params object[] args)
{
if (method == null)
throw new ArgumentNullException(nameof(method), "MethodInfo cannot be null!");
if (args.Length > MAX_ARGUMENT)
throw new ArgumentOutOfRangeException(nameof(args), $"Cannot pass more than {MAX_ARGUMENT} arguments!");
var owner = obj as IMyEventOwner;
if (obj != null && owner == null)
throw new InvalidCastException("Provided event target is not of type IMyEventOwner!");
if (!method.HasAttribute<EventAttribute>())
throw new CustomAttributeFormatException("Provided event target does not have the Event attribute! Replication will not succeed!");
//array to hold arguments to pass into DispatchEvent
object[] arguments = new object[DISPATCH_PARAMETERS];
arguments[0] = obj == null ? TryGetStaticCallSite(method) : TryGetCallSite(method, obj);
arguments[1] = endpoint;
arguments[2] = new Vector3D?();
arguments[3] = owner;
//copy supplied arguments into the reflection arguments
for (var i = 0; i < args.Length; i++)
arguments[i + 4] = args[i];
//pad the array out with DBNull, skip last element
//last element should stay null (this is for blocking events -- not used?)
for (var j = args.Length + 4; j < arguments.Length - 1; j++)
arguments[j] = DbNull;
//create an array of Types so we can create a generic method
var argTypes = new Type[GENERIC_PARAMETERS];
//any null arguments (not DBNull) must be of type IMyEventOwner
for (var k = 2; k < arguments.Length; k++)
argTypes[k - 2] = arguments[k]?.GetType() ?? typeof(IMyEventOwner);
var parameters = method.GetParameters();
for (var i = 0; i < parameters.Length; i++)
{
if (argTypes[i + 1] != parameters[i].ParameterType)
throw new TypeLoadException($"Type mismatch on method parameters. Expected {string.Join(", ", parameters.Select(p => p.ParameterType.ToString()))} got {string.Join(", ", argTypes.Select(t => t.ToString()))}");
}
//create a generic method of DispatchEvent and invoke to inject our data into the network
var dispatch = DispatchEventInfo.MakeGenericMethod(argTypes);
dispatch.Invoke(MyMultiplayer.ReplicationLayer, arguments);
}
/// <summary>
/// Broadcasts a static event to all connected clients
/// </summary>
/// <param name="method"></param>
/// <param name="args"></param>
[Obsolete("Old injection system deprecated. Use the generic methods instead.")]
public void RaiseStaticEvent(MethodInfo method, params object[] args)
{
//default(EndpointId) tells the network to broadcast the message
RaiseStaticEvent(method, default(EndpointId), args);
}
/// <summary>
/// Sends a static event to one client by SteamId
/// </summary>
/// <param name="method"></param>
/// <param name="steamId"></param>
/// <param name="args"></param>
[Obsolete("Old injection system deprecated. Use the generic methods instead.")]
public void RaiseStaticEvent(MethodInfo method, ulong steamId, params object[] args)
{
RaiseEvent(method, (object)null, new EndpointId(steamId), args);
}
/// <summary>
/// Sends a static event to one client
/// </summary>
/// <param name="method"></param>
/// <param name="endpoint"></param>
/// <param name="args"></param>
[Obsolete("Old injection system deprecated. Use the generic methods instead.")]
public void RaiseStaticEvent(MethodInfo method, EndpointId endpoint, params object[] args)
{
RaiseEvent(method, (object)null, endpoint, args);
}
private CallSite TryGetStaticCallSite(MethodInfo method)
{
MyTypeTable typeTable = _typeTableGetter.Invoke(MyMultiplayer.ReplicationLayer);
if (!_methodInfoLookupGetter.Invoke(typeTable.StaticEventTable).TryGetValue(method, out CallSite result))
throw new MissingMemberException("Provided event target not found!");
return result;
}
private CallSite TryGetCallSite(MethodInfo method, object arg)
{
MySynchronizedTypeInfo typeInfo = _typeTableGetter.Invoke(MyMultiplayer.ReplicationLayer).Get(arg.GetType());
if (!_methodInfoLookupGetter.Invoke(typeInfo.EventTable).TryGetValue(method, out CallSite result))
throw new MissingMemberException("Provided event target not found!");
return result;
}
#endregion
#region Network Intercept
[Obsolete]
//TODO: Change this to a method patch so I don't have to try to keep up with Keen.
/// <summary>
/// This is the main body of the network intercept system. When messages come in from clients, they are processed here
/// before being passed on to the game server.
///
/// DO NOT modify this method unless you're absolutely sure of what you're doing. This can very easily destabilize the game!
/// </summary>
/// <param name="packet"></param>
private void OnEvent(MyPacket packet)
{
if (_networkHandlers.Count == 0)
{
//pass the message back to the game server
try
{
((MyReplicationLayer)MyMultiplayer.ReplicationLayer).OnEvent(packet);
}
catch (Exception ex)
{
_log.Error(ex);
//crash after logging, bad things could happen if we continue on with bad data
throw;
}
return;
}
var stream = new BitStream();
stream.ResetRead(packet.BitStream);
var networkId = stream.ReadNetworkId();
//this value is unused, but removing this line corrupts the rest of the stream
var blockedNetworkId = stream.ReadNetworkId();
var eventId = (uint)stream.ReadUInt16();
bool flag = stream.ReadBool();
Vector3D? position = new Vector3D?();
if (flag)
position = new Vector3D?(stream.ReadVector3D());
CallSite site;
object obj;
if (networkId.IsInvalid) // Static event
{
site = _typeTableGetter.Invoke(MyMultiplayer.ReplicationLayer).StaticEventTable.Get(eventId);
obj = null;
}
else // Instance event
{
//var sendAs = ((MyReplicationLayer)MyMultiplayer.ReplicationLayer).GetObjectByNetworkId(networkId);
var sendAs = _getObjectByNetworkId((MyReplicationLayer)MyMultiplayer.ReplicationLayer, networkId);
if (sendAs == null)
{
return;
}
var typeInfo = _typeTableGetter.Invoke(MyMultiplayer.ReplicationLayer).Get(sendAs.GetType());
var eventCount = typeInfo.EventTable.Count;
if (eventId < eventCount) // Directly
{
obj = sendAs;
site = typeInfo.EventTable.Get(eventId);
}
else // Through proxy
{
obj = ((IMyProxyTarget)sendAs).Target;
typeInfo = _typeTableGetter.Invoke(MyMultiplayer.ReplicationLayer).Get(obj.GetType());
site = typeInfo.EventTable.Get(eventId - (uint)eventCount); // Subtract max id of Proxy
}
}
//we're handling the network live in the game thread, this needs to go as fast as possible
var discard = false;
foreach (var handler in _networkHandlers)
//Parallel.ForEach(_networkHandlers, handler =>
{
try
{
if (handler.CanHandle(site))
discard |= handler.Handle(packet.Sender.Id.Value, site, stream, obj, packet);
}
catch (Exception ex)
{
//ApplicationLog.Error(ex.ToString());
_log.Error(ex);
}
}
//one of the handlers wants us to discard this packet
if (discard)
return;
//pass the message back to the game server
try
{
((MyReplicationLayer)MyMultiplayer.ReplicationLayer).OnEvent(packet);
}
catch (Exception ex)
{
_log.Error(ex, "Error processing network event!");
_log.Error(ex);
//crash after logging, bad things could happen if we continue on with bad data
throw;
}
}
[Obsolete("Deprecated. Use a method patch instead.")]
/// <inheritdoc />
public void RegisterNetworkHandler(INetworkHandler handler)
{
_log.Warn($"Plugin {handler.GetType().Assembly.FullName} registered a network handler. This system no longer works. Please alert the plugin author.");
return;
var handlerType = handler.GetType().FullName;
var toRemove = new List<INetworkHandler>();
foreach (var item in _networkHandlers)
{
if (item.GetType().FullName == handlerType)
{
//if (ExtenderOptions.IsDebugging)
_log.Error("Network handler already registered! " + handlerType);
toRemove.Add(item);
}
}
foreach (var oldHandler in toRemove)
_networkHandlers.Remove(oldHandler);
_networkHandlers.Add(handler);
}
[Obsolete("Deprecated. Use a method patch instead.")]
/// <inheritdoc />
public bool UnregisterNetworkHandler(INetworkHandler handler)
{
return _networkHandlers.Remove(handler);
}
[Obsolete("Deprecated. Use a method patch instead.")]
public void RegisterNetworkHandlers(params INetworkHandler[] handlers)
{
foreach (var handler in handlers)
RegisterNetworkHandler(handler);
}
#endregion
}
}

View File

@@ -83,7 +83,7 @@ namespace Torch.Managers.PatchManager
private DynamicMethod AllocatePatchMethod() private DynamicMethod AllocatePatchMethod()
{ {
Debug.Assert(_method.DeclaringType != null); Debug.Assert(_method.DeclaringType != null);
var methodName = _method.Name + $"_{_patchSalt++}"; var methodName = "Patched_" + _method.DeclaringType.FullName + _method.Name + $"_{_patchSalt++}";
var returnType = _method is MethodInfo meth ? meth.ReturnType : typeof(void); var returnType = _method is MethodInfo meth ? meth.ReturnType : typeof(void);
var parameters = _method.GetParameters(); var parameters = _method.GetParameters();
var parameterTypes = (_method.IsStatic ? Enumerable.Empty<Type>() : new[] {typeof(object)}) var parameterTypes = (_method.IsStatic ? Enumerable.Empty<Type>() : new[] {typeof(object)})

View File

@@ -1,54 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Sandbox.ModAPI;
using Torch.API;
using Torch.API.Managers;
using Torch.API.ModAPI;
using Torch.API.ModAPI.Ingame;
using VRage.Scripting;
namespace Torch.Managers
{
public class ScriptingManager : IManager
{
private MyScriptWhitelist _whitelist;
public void Attach()
{
_whitelist = MyScriptCompiler.Static.Whitelist;
MyScriptCompiler.Static.AddConditionalCompilationSymbols("TORCH");
MyScriptCompiler.Static.AddReferencedAssemblies(typeof(ITorchBase).Assembly.Location);
MyScriptCompiler.Static.AddImplicitIngameNamespacesFromTypes(typeof(GridExtensions));
using (var whitelist = _whitelist.OpenBatch())
{
whitelist.AllowNamespaceOfTypes(MyWhitelistTarget.ModApi, typeof(TorchAPI));
whitelist.AllowNamespaceOfTypes(MyWhitelistTarget.Both, typeof(GridExtensions));
}
/*
//dump whitelist
var whitelist = new StringBuilder();
foreach (var pair in MyScriptCompiler.Static.Whitelist.GetWhitelist())
{
var split = pair.Key.Split(',');
whitelist.AppendLine("|-");
whitelist.AppendLine($"|{pair.Value} || {split[0]} || {split[1]}");
}
Log.Info(whitelist);*/
}
public void Detach()
{
// TODO unregister whitelist patches
}
public void UnwhitelistType(Type t)
{
throw new NotImplementedException();
}
}
}

View File

@@ -44,7 +44,7 @@ namespace Torch.Managers
private async void CheckAndUpdateTorch() private async void CheckAndUpdateTorch()
{ {
if (!Torch.Config.GetTorchUpdates) if (Torch.Config.NoUpdate || !Torch.Config.GetTorchUpdates)
return; return;
try try

View File

@@ -12,7 +12,7 @@ namespace Torch.Patches
public static class GameAnalyticsPatch public static class GameAnalyticsPatch
{ {
private static readonly Logger _log = LogManager.GetCurrentClassLogger(); private static readonly Logger _log = LogManager.GetCurrentClassLogger();
private static Action<ILogger> _setLogger; private static Action<ILogger, ILogger> _setLogger;
public static void Patch(PatchContext ctx) public static void Patch(PatchContext ctx)
{ {
@@ -27,7 +27,7 @@ namespace Torch.Patches
return; return;
} }
RuntimeHelpers.RunClassConstructor(type.TypeHandle); RuntimeHelpers.RunClassConstructor(type.TypeHandle);
_setLogger = loggerField?.CreateSetter<ILogger>(); _setLogger = loggerField?.CreateSetter<ILogger, ILogger>();
FixLogging(); FixLogging();
ConstructorInfo ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], new ParameterModifier[0]); ConstructorInfo ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], new ParameterModifier[0]);
@@ -42,7 +42,7 @@ namespace Torch.Patches
private static void FixLogging() private static void FixLogging()
{ {
_setLogger(LogManager.GetLogger("GameAnalytics")); _setLogger(null, LogManager.GetLogger("GameAnalytics"));
if (!(LogManager.Configuration is XmlLoggingConfiguration)) if (!(LogManager.Configuration is XmlLoggingConfiguration))
LogManager.Configuration = new XmlLoggingConfiguration(Path.Combine( LogManager.Configuration = new XmlLoggingConfiguration(Path.Combine(
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) ?? Environment.CurrentDirectory, "NLog.config")); Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) ?? Environment.CurrentDirectory, "NLog.config"));

View File

@@ -19,7 +19,7 @@ namespace Torch.Patches
internal static void Patch(PatchContext target) internal static void Patch(PatchContext target)
{ {
ConstructorInfo ctor = typeof(MySandboxGame).GetConstructor(new[] { typeof(string[]) }); ConstructorInfo ctor = typeof(MySandboxGame).GetConstructor(new[] { typeof(string[]), typeof(IntPtr) });
if (ctor == null) if (ctor == null)
throw new ArgumentException("Can't find constructor MySandboxGame(string[])"); throw new ArgumentException("Can't find constructor MySandboxGame(string[])");
target.GetPattern(ctor).Prefixes.Add(MethodRef(PrefixConstructor)); target.GetPattern(ctor).Prefixes.Add(MethodRef(PrefixConstructor));

View File

@@ -67,6 +67,7 @@ namespace Torch.Patches
if (!Game.IsDedicated && MySession.Static != null) if (!Game.IsDedicated && MySession.Static != null)
ShowWorldSaveResult(tmpSnapshot.SavingSuccess); ShowWorldSaveResult(tmpSnapshot.SavingSuccess);
saveTaskSource.TrySetResult(tmpSnapshot.SavingSuccess ? GameSaveResult.Success : GameSaveResult.FailedToSaveToDisk); saveTaskSource.TrySetResult(tmpSnapshot.SavingSuccess ? GameSaveResult.Success : GameSaveResult.FailedToSaveToDisk);
return false;
}); });
}); });
return saveTaskSource.Task; return saveTaskSource.Task;

View File

@@ -212,7 +212,6 @@
<Compile Include="Event\EventManager.cs" /> <Compile Include="Event\EventManager.cs" />
<Compile Include="Event\IEventList.cs" /> <Compile Include="Event\IEventList.cs" />
<Compile Include="Managers\KeenLogPatch.cs" /> <Compile Include="Managers\KeenLogPatch.cs" />
<Compile Include="Managers\NetworkManager\NetworkManager_Deprecated.cs" />
<Compile Include="Managers\PatchManager\AssemblyMemory.cs" /> <Compile Include="Managers\PatchManager\AssemblyMemory.cs" />
<Compile Include="Managers\PatchManager\DecoratedMethod.cs" /> <Compile Include="Managers\PatchManager\DecoratedMethod.cs" />
<Compile Include="Managers\PatchManager\EmitExtensions.cs" /> <Compile Include="Managers\PatchManager\EmitExtensions.cs" />
@@ -259,7 +258,6 @@
<Compile Include="Managers\EntityManager.cs" /> <Compile Include="Managers\EntityManager.cs" />
<Compile Include="Managers\FilesystemManager.cs" /> <Compile Include="Managers\FilesystemManager.cs" />
<Compile Include="Managers\Manager.cs" /> <Compile Include="Managers\Manager.cs" />
<Compile Include="Managers\NetworkManager\NetworkHandlerBase.cs" />
<Compile Include="Managers\NetworkManager\NetworkManager.cs" /> <Compile Include="Managers\NetworkManager\NetworkManager.cs" />
<Compile Include="Managers\MultiplayerManagerBase.cs" /> <Compile Include="Managers\MultiplayerManagerBase.cs" />
<Compile Include="Managers\UpdateManager.cs" /> <Compile Include="Managers\UpdateManager.cs" />
@@ -279,7 +277,6 @@
<Compile Include="Utils\Reflected\ReflectedSetterAttribute.cs" /> <Compile Include="Utils\Reflected\ReflectedSetterAttribute.cs" />
<Compile Include="Utils\Reflected\ReflectedStaticMethodAttribute.cs" /> <Compile Include="Utils\Reflected\ReflectedStaticMethodAttribute.cs" />
<Compile Include="Utils\Reflection.cs" /> <Compile Include="Utils\Reflection.cs" />
<Compile Include="Managers\ScriptingManager.cs" />
<Compile Include="Utils\SteamWorkshopTools\WebAPI.cs" /> <Compile Include="Utils\SteamWorkshopTools\WebAPI.cs" />
<Compile Include="Utils\StringUtils.cs" /> <Compile Include="Utils\StringUtils.cs" />
<Compile Include="Utils\SynchronizationExtensions.cs" /> <Compile Include="Utils\SynchronizationExtensions.cs" />

View File

@@ -49,6 +49,7 @@ using VRage.Game.SessionComponents;
using VRage.GameServices; using VRage.GameServices;
using VRage.Library; using VRage.Library;
using VRage.ObjectBuilders; using VRage.ObjectBuilders;
using VRage.Platform.Windows;
using VRage.Plugins; using VRage.Plugins;
using VRage.Scripting; using VRage.Scripting;
using VRage.Steam; using VRage.Steam;
@@ -64,6 +65,7 @@ namespace Torch
{ {
static TorchBase() static TorchBase()
{ {
MyVRageWindows.Init("SpaceEngineersDedicated", MySandboxGame.Log, null, false);
ReflectedManager.Process(typeof(TorchBase).Assembly); ReflectedManager.Process(typeof(TorchBase).Assembly);
ReflectedManager.Process(typeof(ITorchBase).Assembly); ReflectedManager.Process(typeof(ITorchBase).Assembly);
PatchManager.AddPatchShim(typeof(GameStatePatchShim)); PatchManager.AddPatchShim(typeof(GameStatePatchShim));
@@ -153,7 +155,6 @@ namespace Torch
Plugins = new PluginManager(this); Plugins = new PluginManager(this);
var sessionManager = new TorchSessionManager(this); var sessionManager = new TorchSessionManager(this);
sessionManager.AddFactory((x) => MyMultiplayer.Static?.SyncLayer != null ? new NetworkManager(this) : null);
sessionManager.AddFactory((x) => Sync.IsServer ? new ChatManagerServer(this) : new ChatManagerClient(this)); sessionManager.AddFactory((x) => Sync.IsServer ? new ChatManagerServer(this) : new ChatManagerClient(this));
sessionManager.AddFactory((x) => Sync.IsServer ? new CommandManager(this) : null); sessionManager.AddFactory((x) => Sync.IsServer ? new CommandManager(this) : null);
sessionManager.AddFactory((x) => new EntityManager(this)); sessionManager.AddFactory((x) => new EntityManager(this));

View File

@@ -30,8 +30,6 @@ using VRage.Game;
using VRage.Game.ObjectBuilder; using VRage.Game.ObjectBuilder;
using VRage.Game.SessionComponents; using VRage.Game.SessionComponents;
using VRage.GameServices; using VRage.GameServices;
using VRage.Network;
using VRage.Platform.Windows;
using VRage.Plugins; using VRage.Plugins;
using VRage.Steam; using VRage.Steam;
using VRage.Utils; using VRage.Utils;
@@ -157,8 +155,6 @@ namespace Torch
_tweakGameSettings(); _tweakGameSettings();
MyFileSystem.Reset(); MyFileSystem.Reset();
VRage.Platform.Windows.MyVRageWindows.Init(MySandboxGame.Log, Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "SpaceEngineersDedicated"));
MyVRageWindows.Init(MySandboxGame.Log, Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "SpaceEngineersDedicated"));
MyInitializer.InvokeBeforeRun(_appSteamId, _appName, _userDataPath); MyInitializer.InvokeBeforeRun(_appSteamId, _appName, _userDataPath);
// MyInitializer.InitCheckSum(); // MyInitializer.InitCheckSum();

View File

@@ -221,7 +221,6 @@ namespace Torch.Views
var gt = propertyType.GetGenericArguments()[0]; var gt = propertyType.GetGenericArguments()[0];
//TODO: Is this the best option? Probably not
if (gt.IsPrimitive || gt == typeof(string)) if (gt.IsPrimitive || gt == typeof(string))
{ {
button.Click += (sender, args) => EditPrimitiveCollection(((Button)sender).DataContext); button.Click += (sender, args) => EditPrimitiveCollection(((Button)sender).DataContext);