Merge branch 'master' into Patron
This commit is contained in:
@@ -18,6 +18,8 @@ namespace Torch
|
|||||||
bool ShouldUpdateTorch { get; }
|
bool ShouldUpdateTorch { get; }
|
||||||
int TickTimeout { get; set; }
|
int TickTimeout { get; set; }
|
||||||
string WaitForPID { get; set; }
|
string WaitForPID { get; set; }
|
||||||
|
string ChatName { get; set; }
|
||||||
|
string ChatColor { get; set; }
|
||||||
|
|
||||||
bool Save(string path = null);
|
bool Save(string path = null);
|
||||||
}
|
}
|
||||||
|
@@ -95,6 +95,10 @@ namespace Torch.API.WebAPI
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
path = path ?? $"Plugins\\{item.Name}.zip";
|
path = path ?? $"Plugins\\{item.Name}.zip";
|
||||||
|
string relpath = Path.GetDirectoryName(path);
|
||||||
|
|
||||||
|
Directory.CreateDirectory(relpath);
|
||||||
|
|
||||||
var h = await _client.GetAsync(string.Format(PLUGIN_QUERY, item.ID));
|
var h = await _client.GetAsync(string.Format(PLUGIN_QUERY, item.ID));
|
||||||
string res = await h.Content.ReadAsStringAsync();
|
string res = await h.Content.ReadAsStringAsync();
|
||||||
var response = JsonConvert.DeserializeObject<PluginFullItem>(res);
|
var response = JsonConvert.DeserializeObject<PluginFullItem>(res);
|
||||||
@@ -110,7 +114,11 @@ namespace Torch.API.WebAPI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var s = await _client.GetStreamAsync(version.URL);
|
var s = await _client.GetStreamAsync(version.URL);
|
||||||
using (var f = new FileStream(path, FileMode.Create))
|
|
||||||
|
if(File.Exists(path))
|
||||||
|
File.Delete(path);
|
||||||
|
|
||||||
|
using (var f = File.Create(path))
|
||||||
{
|
{
|
||||||
await s.CopyToAsync(f);
|
await s.CopyToAsync(f);
|
||||||
await f.FlushAsync();
|
await f.FlushAsync();
|
||||||
|
@@ -5,6 +5,7 @@ using System.Windows;
|
|||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using VRage.Game;
|
||||||
|
|
||||||
namespace Torch.Server
|
namespace Torch.Server
|
||||||
{
|
{
|
||||||
@@ -60,6 +61,10 @@ namespace Torch.Server
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public List<string> Plugins { get; set; } = new List<string>();
|
public List<string> Plugins { get; set; } = new List<string>();
|
||||||
|
|
||||||
|
public string ChatName { get; set; } = "Server";
|
||||||
|
|
||||||
|
public string ChatColor { get; set; } = "Red";
|
||||||
|
|
||||||
public bool EnableWhitelist { get; set; } = false;
|
public bool EnableWhitelist { get; set; } = false;
|
||||||
public HashSet<ulong> Whitelist { get; set; } = new HashSet<ulong>();
|
public HashSet<ulong> Whitelist { get; set; } = new HashSet<ulong>();
|
||||||
|
|
||||||
|
@@ -17,8 +17,8 @@
|
|||||||
<ColumnDefinition/>
|
<ColumnDefinition/>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Button Grid.Column="1" x:Name="Send" Content="Send" DockPanel.Dock="Right" Width="50" Margin="5,5,5,5" Click="SendButton_Click"></Button>
|
<Button Grid.Column="1" Content="Send" DockPanel.Dock="Right" Width="50" Margin="5" Click="SendButton_Click"></Button>
|
||||||
<TextBox Grid.Column="0" x:Name="Message" DockPanel.Dock="Left" Margin="5,5,5,5" KeyDown="Message_OnKeyDown"></TextBox>
|
<TextBox Grid.Column="0" x:Name="Message" Margin="5" KeyDown="Message_OnKeyDown"></TextBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
@@ -55,10 +55,17 @@ namespace Torch.Commands
|
|||||||
Args = args ?? new List<string>();
|
Args = args ?? new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Respond(string message, string sender = "Server", string font = MyFontEnum.Blue)
|
public virtual void Respond(string message, string sender = null, string font = MyFontEnum.Blue)
|
||||||
{
|
{
|
||||||
Torch.CurrentSession.Managers.GetManager<IChatManagerServer>()
|
var chat = Torch.CurrentSession.Managers.GetManager<IChatManagerServer>();
|
||||||
?.SendMessageAsOther(sender, message, font, _steamIdSender);
|
if (sender != null)
|
||||||
|
{
|
||||||
|
chat?.SendMessageAsOther(sender, message, font, _steamIdSender);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chat?.SendMessageAsSelf(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -38,10 +38,18 @@ namespace Torch.Managers.ChatManager
|
|||||||
{
|
{
|
||||||
if (Sandbox.Engine.Platform.Game.IsDedicated)
|
if (Sandbox.Engine.Platform.Game.IsDedicated)
|
||||||
{
|
{
|
||||||
|
// Sending invalid color to clients will crash them. KEEEN
|
||||||
|
var color = Torch.Config.ChatColor;
|
||||||
|
if (!StringUtils.IsFontEnum(Torch.Config.ChatColor))
|
||||||
|
{
|
||||||
|
_log.Warn("Invalid chat font color! Defaulting to 'Red'");
|
||||||
|
color = MyFontEnum.Red;
|
||||||
|
}
|
||||||
|
|
||||||
var scripted = new ScriptedChatMsg()
|
var scripted = new ScriptedChatMsg()
|
||||||
{
|
{
|
||||||
Author = "Server",
|
Author = Torch.Config.ChatName,
|
||||||
Font = MyFontEnum.Red,
|
Font = color,
|
||||||
Text = message,
|
Text = message,
|
||||||
Target = 0
|
Target = 0
|
||||||
};
|
};
|
||||||
|
@@ -68,6 +68,10 @@ namespace Torch.Managers
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Attach()
|
public override void Attach()
|
||||||
{
|
{
|
||||||
|
//disable all this for now
|
||||||
|
_log.Warn("Network intercept disabled. Some plugins may not work correctly.");
|
||||||
|
return;
|
||||||
|
|
||||||
if (_init)
|
if (_init)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -362,6 +366,9 @@ namespace Torch.Managers
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void RegisterNetworkHandler(INetworkHandler handler)
|
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 handlerType = handler.GetType().FullName;
|
||||||
var toRemove = new List<INetworkHandler>();
|
var toRemove = new List<INetworkHandler>();
|
||||||
foreach (var item in _networkHandlers)
|
foreach (var item in _networkHandlers)
|
||||||
|
54
Torch/Patches/PhysicsMemoryPatch.cs
Normal file
54
Torch/Patches/PhysicsMemoryPatch.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Havok;
|
||||||
|
using Sandbox;
|
||||||
|
using Sandbox.Engine.Physics;
|
||||||
|
using Sandbox.Game.World;
|
||||||
|
using Torch.Managers.PatchManager;
|
||||||
|
using Torch.Mod;
|
||||||
|
using Torch.Mod.Messages;
|
||||||
|
using VRage.Game;
|
||||||
|
|
||||||
|
namespace Torch.Patches
|
||||||
|
{
|
||||||
|
[PatchShim]
|
||||||
|
public static class PhysicsMemoryPatch
|
||||||
|
{
|
||||||
|
public static void Patch(PatchContext ctx)
|
||||||
|
{
|
||||||
|
ctx.GetPattern(typeof(MyPhysics).GetMethod("StepWorldsInternal", BindingFlags.NonPublic | BindingFlags.Instance)).Prefixes.Add(typeof(PhysicsMemoryPatch).GetMethod(nameof(PrefixPhysics)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool NotifiedFailure { get; private set; }
|
||||||
|
|
||||||
|
public static bool PrefixPhysics()
|
||||||
|
{
|
||||||
|
if (!HkBaseSystem.IsOutOfMemory)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (NotifiedFailure)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
NotifiedFailure = true;
|
||||||
|
ModCommunication.SendMessageToClients(new NotificationMessage("Havok has run out of memory. Server will restart in 30 seconds!", 60000, MyFontEnum.Red));
|
||||||
|
//save the session NOW before anything moves due to weird physics.
|
||||||
|
MySession.Static.Save();
|
||||||
|
//pause the game, for funsies
|
||||||
|
MySandboxGame.IsPaused = true;
|
||||||
|
|
||||||
|
//nasty hack
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
Thread.Sleep(TimeSpan.FromSeconds(30));
|
||||||
|
TorchBase.Instance.Restart();
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -66,7 +66,7 @@ namespace Torch.Patches
|
|||||||
{
|
{
|
||||||
if (!Game.IsDedicated && MySession.Static != null)
|
if (!Game.IsDedicated && MySession.Static != null)
|
||||||
ShowWorldSaveResult(tmpSnapshot.SavingSuccess);
|
ShowWorldSaveResult(tmpSnapshot.SavingSuccess);
|
||||||
saveTaskSource.SetResult(tmpSnapshot.SavingSuccess ? GameSaveResult.Success : GameSaveResult.FailedToSaveToDisk);
|
saveTaskSource.TrySetResult(tmpSnapshot.SavingSuccess ? GameSaveResult.Success : GameSaveResult.FailedToSaveToDisk);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return saveTaskSource.Task;
|
return saveTaskSource.Task;
|
||||||
|
@@ -23,8 +23,12 @@ namespace Torch
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A GitHub repository in the format of Author/Repository to retrieve plugin updates.
|
/// A GitHub repository in the format of Author/Repository to retrieve plugin updates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Obsolete("Updates no longer check git. Updates are hosted only on torchapi.net")]
|
||||||
public string Repository { get; set; }
|
public string Repository { get; set; }
|
||||||
|
|
||||||
|
//xml tomfoolery
|
||||||
|
public bool ShouldSerializeRepository() => false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The plugin version. This must include a string in the format of #[.#[.#]] for update checking purposes.
|
/// The plugin version. This must include a string in the format of #[.#[.#]] for update checking purposes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -224,6 +224,7 @@
|
|||||||
<Compile Include="Patches\GameAnalyticsPatch.cs" />
|
<Compile Include="Patches\GameAnalyticsPatch.cs" />
|
||||||
<Compile Include="Patches\GameStatePatchShim.cs" />
|
<Compile Include="Patches\GameStatePatchShim.cs" />
|
||||||
<Compile Include="Patches\ObjectFactoryInitPatch.cs" />
|
<Compile Include="Patches\ObjectFactoryInitPatch.cs" />
|
||||||
|
<Compile Include="Patches\PhysicsMemoryPatch.cs" />
|
||||||
<Compile Include="Patches\SessionDownloadPatch.cs" />
|
<Compile Include="Patches\SessionDownloadPatch.cs" />
|
||||||
<Compile Include="Patches\TorchAsyncSaving.cs" />
|
<Compile Include="Patches\TorchAsyncSaving.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
@@ -485,6 +485,7 @@ namespace Torch
|
|||||||
if (_registeredAuxAssemblies.Add(asm))
|
if (_registeredAuxAssemblies.Add(asm))
|
||||||
{
|
{
|
||||||
ReflectedManager.Process(asm);
|
ReflectedManager.Process(asm);
|
||||||
|
PatchManager.AddPatchShims(asm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -60,5 +61,13 @@ namespace Torch.Utils
|
|||||||
}
|
}
|
||||||
return builder?.ToString() ?? "";
|
return builder?.ToString() ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string[] FontEnumValues => _fontEnumValues ?? (_fontEnumValues = typeof(VRage.Game.MyFontEnum).GetFields(BindingFlags.Public | BindingFlags.Static).Where(x => x.IsLiteral && !x.IsInitOnly).Select(x => (string)x.GetValue(null)).ToArray());
|
||||||
|
|
||||||
|
private static string[] _fontEnumValues;
|
||||||
|
public static bool IsFontEnum(string str)
|
||||||
|
{
|
||||||
|
return FontEnumValues.Contains(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user