# Torch 1.1.229.265
* Features - Added more lenient version parsing for plugins (v#.# should work) - Added countdown option to restart command (!restart [seconds]) * Fixes - General fixes to work with the latest SE version - Fixed config changes not saving - Fixed crash on servers using the Windows Classic theme
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
# Torch 1.1.229.265
|
||||
* Features
|
||||
- Added more lenient version parsing for plugins (v#.# should work)
|
||||
- Added countdown option to restart command (!restart [seconds])
|
||||
* Fixes
|
||||
- General fixes to work with the latest SE version
|
||||
- Fixed config changes not saving
|
||||
- (hopefully) Fixed issue causing crashes on servers using the Windows Classic theme
|
||||
|
||||
# Torch 1.1.207.7
|
||||
* Notes
|
||||
- This release makes significant changes to TorchConfig.xml. It has been renamed to Torch.cfg and has different options.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion("1.0.213.390")]
|
||||
[assembly: AssemblyFileVersion("1.0.213.390")]
|
||||
[assembly: AssemblyVersion("1.0.229.265")]
|
||||
[assembly: AssemblyFileVersion("1.0.229.265")]
|
@@ -103,6 +103,9 @@
|
||||
<HintPath>..\GameBinaries\VRage.Render11.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="VRage.Steam">
|
||||
<HintPath>..\..\..\..\..\..\..\steamcmd\steamapps\common\SpaceEngineersDedicatedServer\DedicatedServer64\VRage.Steam.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
|
@@ -11,6 +11,7 @@ using Sandbox.Engine.Utils;
|
||||
using Sandbox.Game;
|
||||
using Sandbox.ModAPI;
|
||||
using SpaceEngineers.Game;
|
||||
using VRage.Steam;
|
||||
using Torch.API;
|
||||
using VRage.FileSystem;
|
||||
using VRageRender;
|
||||
@@ -22,7 +23,6 @@ namespace Torch.Client
|
||||
private MyCommonProgramStartup _startup;
|
||||
private IMyRender _renderer;
|
||||
private const uint APP_ID = 244850;
|
||||
private VRageGameServices _services;
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
@@ -59,7 +59,6 @@ namespace Torch.Client
|
||||
|
||||
InitializeRender();
|
||||
|
||||
_services = new VRageGameServices(mySteamService);
|
||||
if (!Game.IsDedicated)
|
||||
MyFileSystem.InitUserSpecific(mySteamService.UserId.ToString());
|
||||
}
|
||||
@@ -85,7 +84,7 @@ namespace Torch.Client
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
using (var spaceEngineersGame = new SpaceEngineersGame(_services, RunArgs))
|
||||
using (var spaceEngineersGame = new SpaceEngineersGame(RunArgs))
|
||||
{
|
||||
Log.Info("Starting client");
|
||||
spaceEngineersGame.OnGameLoaded += SpaceEngineersGame_OnGameLoaded;
|
||||
|
59
Torch.Server/ListBoxExtensions.cs
Normal file
59
Torch.Server/ListBoxExtensions.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Torch.Server
|
||||
{
|
||||
public static class ListBoxExtensions
|
||||
{
|
||||
//https://stackoverflow.com/questions/28689125/how-to-autoscroll-listbox-to-bottom-wpf-c
|
||||
public static void ScrollToItem(this ListBox listBox, int index)
|
||||
{
|
||||
// Find a container
|
||||
UIElement container = null;
|
||||
for (int i = index; i > 0; i--)
|
||||
{
|
||||
container = listBox.ItemContainerGenerator.ContainerFromIndex(i) as UIElement;
|
||||
if (container != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (container == null)
|
||||
return;
|
||||
|
||||
// Find the ScrollContentPresenter
|
||||
ScrollContentPresenter presenter = null;
|
||||
for (Visual vis = container; vis != null && vis != listBox; vis = VisualTreeHelper.GetParent(vis) as Visual)
|
||||
if ((presenter = vis as ScrollContentPresenter) != null)
|
||||
break;
|
||||
if (presenter == null)
|
||||
return;
|
||||
|
||||
// Find the IScrollInfo
|
||||
var scrollInfo =
|
||||
!presenter.CanContentScroll ? presenter :
|
||||
presenter.Content as IScrollInfo ??
|
||||
FirstVisualChild(presenter.Content as ItemsPresenter) as IScrollInfo ??
|
||||
presenter;
|
||||
|
||||
// Find the amount of items that is "Visible" in the ListBox
|
||||
var height = (container as ListBoxItem).ActualHeight;
|
||||
var lbHeight = listBox.ActualHeight;
|
||||
var showCount = (int)Math.Floor(lbHeight / height) - 1;
|
||||
|
||||
//Set the scrollbar
|
||||
if (scrollInfo.CanVerticallyScroll)
|
||||
scrollInfo.SetVerticalOffset(index - showCount);
|
||||
}
|
||||
|
||||
private static DependencyObject FirstVisualChild(Visual visual)
|
||||
{
|
||||
if (visual == null) return null;
|
||||
if (VisualTreeHelper.GetChildrenCount(visual) == 0) return null;
|
||||
return VisualTreeHelper.GetChild(visual, 0);
|
||||
}
|
||||
}
|
||||
}
|
@@ -129,7 +129,7 @@ namespace Torch.Server.Managers
|
||||
|
||||
public void SaveConfig()
|
||||
{
|
||||
DedicatedConfig.Model.Save();
|
||||
DedicatedConfig.Save();
|
||||
Log.Info("Saved dedicated config.");
|
||||
|
||||
try
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion("1.1.213.390")]
|
||||
[assembly: AssemblyFileVersion("1.1.213.390")]
|
||||
[assembly: AssemblyVersion("1.1.229.265")]
|
||||
[assembly: AssemblyFileVersion("1.1.229.265")]
|
@@ -185,6 +185,7 @@
|
||||
<Reference Include="PresentationFramework" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ListBoxExtensions.cs" />
|
||||
<Compile Include="Managers\InstanceManager.cs" />
|
||||
<Compile Include="NativeMethods.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
|
@@ -79,7 +79,7 @@ namespace Torch.Server
|
||||
MyFinalBuildConstants.APP_VERSION = MyPerGameSettings.BasicGameInfo.GameVersion;
|
||||
InvokeBeforeRun();
|
||||
|
||||
MyObjectBuilderSerializer.RegisterFromAssembly(typeof(MyObjectBuilder_CheckpointSerializer).Assembly);
|
||||
//MyObjectBuilderSerializer.RegisterFromAssembly(typeof(MyObjectBuilder_CheckpointSerializer).Assembly);
|
||||
MyPlugins.RegisterGameAssemblyFile(MyPerGameSettings.GameModAssembly);
|
||||
MyPlugins.RegisterGameObjectBuildersAssemblyFile(MyPerGameSettings.GameModObjBuildersAssembly);
|
||||
MyPlugins.RegisterSandboxAssemblyFile(MyPerGameSettings.SandboxAssembly);
|
||||
@@ -131,7 +131,6 @@ namespace Torch.Server
|
||||
_uptime = Stopwatch.StartNew();
|
||||
IsRunning = true;
|
||||
GameThread = Thread.CurrentThread;
|
||||
Config.Save();
|
||||
State = ServerState.Starting;
|
||||
Log.Info("Starting server.");
|
||||
|
||||
|
@@ -74,6 +74,12 @@ namespace Torch.Server.ViewModels
|
||||
{
|
||||
get => _settings.HackSpeedMultiplier; set { _settings.HackSpeedMultiplier = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="MyObjectBuilder_SessionSettings.WelderSpeedMultiplier"/>
|
||||
public float WelderSpeedMultiplier
|
||||
{
|
||||
get => _settings.WelderSpeedMultiplier; set { _settings.WelderSpeedMultiplier = value; OnPropertyChanged(); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region NPCs
|
||||
|
@@ -49,12 +49,15 @@ namespace Torch.Server
|
||||
|
||||
private void ChatHistory_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
ChatItems.ScrollToItem(ChatItems.Items.Count - 1);
|
||||
/*
|
||||
if (VisualTreeHelper.GetChildrenCount(ChatItems) > 0)
|
||||
{
|
||||
|
||||
Border border = (Border)VisualTreeHelper.GetChild(ChatItems, 0);
|
||||
ScrollViewer scrollViewer = (ScrollViewer)VisualTreeHelper.GetChild(border, 0);
|
||||
scrollViewer.ScrollToBottom();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
private void SendButton_Click(object sender, RoutedEventArgs e)
|
||||
|
@@ -104,6 +104,10 @@
|
||||
<TextBox Text="{Binding AssemblerSpeedMultiplier}" Margin="3" Width="70" />
|
||||
<Label Content="Assembler Speed" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox Text="{Binding WelderSpeedMultiplier}" Margin="3" Width="70" />
|
||||
<Label Content="Welder Speed" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox Text="{Binding GrinderSpeedMultiplier}" Margin="3" Width="70" />
|
||||
<Label Content="Grinder Speed" />
|
||||
|
@@ -1,34 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Xml.Serialization;
|
||||
using NLog;
|
||||
using Sandbox;
|
||||
using Sandbox.Engine.Networking;
|
||||
using Sandbox.Engine.Utils;
|
||||
using Torch.Server.Managers;
|
||||
using Torch.Server.ViewModels;
|
||||
using Torch.Views;
|
||||
using VRage;
|
||||
using VRage.Dedicated;
|
||||
using VRage.Game;
|
||||
using VRage.ObjectBuilders;
|
||||
using Path = System.IO.Path;
|
||||
|
||||
namespace Torch.Server.Views
|
||||
{
|
||||
|
@@ -65,7 +65,7 @@ namespace Torch.Server
|
||||
|
||||
private void BtnStart_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_config.Save();
|
||||
_server.GetManager<InstanceManager>().SaveConfig();
|
||||
new Thread(_server.Start).Start();
|
||||
}
|
||||
|
||||
@@ -80,7 +80,6 @@ namespace Torch.Server
|
||||
_config.WindowSize = newSize;
|
||||
var newPos = new Point((int)Left, (int)Top);
|
||||
_config.WindowPosition = newPos;
|
||||
_config.Save();
|
||||
|
||||
if (_server?.State == ServerState.Running)
|
||||
_server.Stop();
|
||||
|
@@ -1,8 +1,11 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using Sandbox.ModAPI;
|
||||
using Torch;
|
||||
using Torch.Commands.Permissions;
|
||||
@@ -106,12 +109,48 @@ namespace Torch.Commands
|
||||
}
|
||||
|
||||
[Command("restart", "Restarts the server.")]
|
||||
public void Restart(bool save = true)
|
||||
public void Restart(int countdownSeconds = 10, bool save = true)
|
||||
{
|
||||
Context.Respond("Restarting server.");
|
||||
if (save)
|
||||
Context.Torch.Save(Context.Player?.IdentityId ?? 0).Wait();
|
||||
Task.Run(() =>
|
||||
{
|
||||
var countdown = RestartCountdown(countdownSeconds).GetEnumerator();
|
||||
while (countdown.MoveNext())
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private IEnumerable RestartCountdown(int countdown)
|
||||
{
|
||||
for (var i = countdown; i >= 0; i--)
|
||||
{
|
||||
if (i >= 60 && i % 60 == 0)
|
||||
{
|
||||
Context.Torch.Multiplayer.SendMessage($"Restarting server in {i / 60} minute{Pluralize(i / 60)}.");
|
||||
yield return null;
|
||||
}
|
||||
else if (i > 0)
|
||||
{
|
||||
if (i < 11)
|
||||
Context.Torch.Multiplayer.SendMessage($"Restarting server in {i} second{Pluralize(i)}.");
|
||||
yield return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Context.Torch.Invoke(() =>
|
||||
{
|
||||
Context.Torch.Save(0).Wait();
|
||||
Context.Torch.Restart();
|
||||
});
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string Pluralize(int num)
|
||||
{
|
||||
return num == 1 ? "" : "s";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -45,7 +45,7 @@ namespace Torch.Managers
|
||||
}
|
||||
}
|
||||
|
||||
private void Static_ChatMessageReceived(ulong arg1, string arg2, SteamSDK.ChatEntryTypeEnum arg3)
|
||||
private void Static_ChatMessageReceived(ulong arg1, string arg2)
|
||||
{
|
||||
var msg = new ChatMsg {Author = arg1, Text = arg2};
|
||||
var sendToOthers = true;
|
||||
|
@@ -28,6 +28,7 @@ using Torch.Commands;
|
||||
using Torch.ViewModels;
|
||||
using VRage.Game;
|
||||
using VRage.Game.ModAPI;
|
||||
using VRage.GameServices;
|
||||
using VRage.Library.Collections;
|
||||
using VRage.Network;
|
||||
using VRage.Utils;
|
||||
@@ -169,10 +170,10 @@ namespace Torch.Managers
|
||||
|
||||
private void OnClientKicked(ulong steamId)
|
||||
{
|
||||
OnClientLeft(steamId, ChatMemberStateChangeEnum.Kicked);
|
||||
OnClientLeft(steamId, MyChatMemberStateChangeEnum.Kicked);
|
||||
}
|
||||
|
||||
private void OnClientLeft(ulong steamId, ChatMemberStateChangeEnum stateChange)
|
||||
private void OnClientLeft(ulong steamId, MyChatMemberStateChangeEnum stateChange)
|
||||
{
|
||||
Players.TryGetValue(steamId, out PlayerViewModel vm);
|
||||
if (vm == null)
|
||||
|
@@ -6,6 +6,7 @@ using System.IO.Packaging;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
@@ -52,7 +53,8 @@ namespace Torch.Managers
|
||||
return new Tuple<Version, string>(new Version(), null);
|
||||
|
||||
var zip = latest.Assets.FirstOrDefault(x => x.Name.Contains(".zip"));
|
||||
return new Tuple<Version, string>(new Version(latest.TagName ?? "0"), zip?.BrowserDownloadUrl);
|
||||
var versionName = Regex.Match(latest.TagName, "(\\d+\\.)+\\d+").ToString();
|
||||
return new Tuple<Version, string>(new Version(string.IsNullOrWhiteSpace(versionName) ? versionName : "0.0"), zip?.BrowserDownloadUrl);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -114,6 +116,7 @@ namespace Torch.Managers
|
||||
new WebClient().DownloadFile(new Uri(releaseInfo.Item2), updateName);
|
||||
UpdateFromZip(updateName, _torchDir);
|
||||
File.Delete(updateName);
|
||||
_log.Warn($"Torch version {releaseInfo.Item1} has been installed, please restart Torch to finish the process.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SteamSDK;
|
||||
using VRage.Steam;
|
||||
using Sandbox;
|
||||
|
||||
namespace Torch
|
||||
@@ -16,34 +17,48 @@ namespace Torch
|
||||
/// </summary>
|
||||
public class SteamService : MySteamService
|
||||
{
|
||||
public SteamService(bool isDedicated, uint appId) : base(true, appId)
|
||||
public SteamService(bool isDedicated, uint appId)
|
||||
: base(true, appId)
|
||||
{
|
||||
// TODO: Add protection for this mess... somewhere
|
||||
SteamServerAPI.Instance.Dispose();
|
||||
SteamSDK.SteamServerAPI.Instance.Dispose();
|
||||
var steam = typeof(MySteamService);
|
||||
steam.GetField("SteamServerAPI").SetValue(this, null);
|
||||
|
||||
steam.GetProperty("SteamServerAPI").GetSetMethod(true).Invoke(this, new object[] { null });
|
||||
steam.GetField("m_gameServer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(this, null);
|
||||
|
||||
steam.GetProperty("AppId").GetSetMethod(true).Invoke(this, new object[] { appId });
|
||||
if (isDedicated)
|
||||
{
|
||||
steam.GetField("SteamServerAPI").SetValue(this, SteamServerAPI.Instance);
|
||||
steam.GetProperty("SteamServerAPI").GetSetMethod(true).Invoke(this, new object[] { null });
|
||||
steam.GetField("m_gameServer").SetValue(this, new MySteamGameServer());
|
||||
}
|
||||
else
|
||||
{
|
||||
var steamApi = SteamAPI.Instance;
|
||||
steam.GetField("SteamAPI").SetValue(this, SteamAPI.Instance);
|
||||
steam.GetProperty("IsActive").GetSetMethod(true).Invoke(this, new object[] { SteamAPI.Instance != null });
|
||||
var SteamAPI = SteamSDK.SteamAPI.Instance;
|
||||
steam.GetProperty("API").GetSetMethod(true).Invoke(this, new object[] { SteamAPI.Instance });
|
||||
steam.GetProperty("IsActive").GetSetMethod(true).Invoke(this, new object[] {
|
||||
SteamAPI.Instance.Init()
|
||||
});
|
||||
|
||||
if (steamApi != null)
|
||||
if (IsActive)
|
||||
{
|
||||
steam.GetProperty("UserId").GetSetMethod(true).Invoke(this, new object[] { steamApi.GetSteamUserId() });
|
||||
steam.GetProperty("UserName").GetSetMethod(true).Invoke(this, new object[] { steamApi.GetSteamName() });
|
||||
steam.GetProperty("OwnsGame").GetSetMethod(true).Invoke(this, new object[] { steamApi.HasGame() });
|
||||
steam.GetProperty("UserUniverse").GetSetMethod(true).Invoke(this, new object[] { steamApi.GetSteamUserUniverse() });
|
||||
steam.GetProperty("BranchName").GetSetMethod(true).Invoke(this, new object[] { steamApi.GetBranchName() });
|
||||
steamApi.LoadStats();
|
||||
}
|
||||
}
|
||||
steam.GetProperty("UserId").GetSetMethod(true).Invoke(this, new object[] { SteamAPI.GetSteamUserId() });
|
||||
steam.GetProperty("UserName").GetSetMethod(true).Invoke(this, new object[] { SteamAPI.GetSteamName() });
|
||||
steam.GetProperty("OwnsGame").GetSetMethod(true).Invoke(this, new object[] { SteamAPI.HasGame() });
|
||||
steam.GetProperty("UserUniverse").GetSetMethod(true).Invoke(this, new object[] { SteamAPI.GetSteamUserUniverse() });
|
||||
steam.GetProperty("BranchName").GetSetMethod(true).Invoke(this, new object[] { SteamAPI.GetBranchName() });
|
||||
SteamAPI.LoadStats();
|
||||
|
||||
steam.GetProperty("InventoryAPI").GetSetMethod(true).Invoke(this, new object[] { new MySteamInventory() });
|
||||
|
||||
steam.GetMethod("RegisterCallbacks",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
|
||||
.Invoke(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
steam.GetProperty("Peer2Peer").GetSetMethod(true).Invoke(this, new object[] { new MySteamPeer2Peer() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -142,6 +142,9 @@
|
||||
<HintPath>..\GameBinaries\VRage.Scripting.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="VRage.Steam">
|
||||
<HintPath>..\..\..\..\..\..\..\steamcmd\steamapps\common\SpaceEngineersDedicatedServer\DedicatedServer64\VRage.Steam.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
Reference in New Issue
Block a user