Added AutoUpdater
This commit is contained in:
@@ -37,7 +37,7 @@ namespace SeamlessClientPlugin.ClientMessages
|
|||||||
{
|
{
|
||||||
MessageType = Type;
|
MessageType = Type;
|
||||||
|
|
||||||
if (!MyAPIGateway.Multiplayer.IsServer)
|
if (MyAPIGateway.Multiplayer != null && !MyAPIGateway.Multiplayer.IsServer)
|
||||||
{
|
{
|
||||||
if(MyAPIGateway.Session.LocalHumanPlayer == null)
|
if(MyAPIGateway.Session.LocalHumanPlayer == null)
|
||||||
{
|
{
|
||||||
|
@@ -9,13 +9,16 @@ using Sandbox.Graphics.GUI;
|
|||||||
using Sandbox.ModAPI;
|
using Sandbox.ModAPI;
|
||||||
using SeamlessClientPlugin.ClientMessages;
|
using SeamlessClientPlugin.ClientMessages;
|
||||||
using SeamlessClientPlugin.SeamlessTransfer;
|
using SeamlessClientPlugin.SeamlessTransfer;
|
||||||
|
using SeamlessClientPlugin.Updater;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
|
using System.Windows.Forms;
|
||||||
using VRage.Input;
|
using VRage.Input;
|
||||||
using VRage.Plugins;
|
using VRage.Plugins;
|
||||||
using VRage.Utils;
|
using VRage.Utils;
|
||||||
@@ -103,11 +106,11 @@ namespace SeamlessClientPlugin
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static string Version = "1.0.0";
|
public static string Version = "1.1.0";
|
||||||
private bool Initilized = false;
|
private bool Initilized = false;
|
||||||
private bool SentPingResponse = false;
|
private bool SentPingResponse = false;
|
||||||
public const ushort SeamlessClientNetID = 2936;
|
public const ushort SeamlessClientNetID = 2936;
|
||||||
private Timer PingTimer = new Timer(2000);
|
private System.Timers.Timer PingTimer = new System.Timers.Timer(3000);
|
||||||
|
|
||||||
public static LoadServer Server = new LoadServer();
|
public static LoadServer Server = new LoadServer();
|
||||||
|
|
||||||
@@ -132,6 +135,19 @@ namespace SeamlessClientPlugin
|
|||||||
public void Init(object gameInstance)
|
public void Init(object gameInstance)
|
||||||
{
|
{
|
||||||
TryShow("Running Seamless Client Plugin v[" + Version + "]");
|
TryShow("Running Seamless Client Plugin v[" + Version + "]");
|
||||||
|
|
||||||
|
UpdateChecker Checker = new UpdateChecker(Version, false);
|
||||||
|
|
||||||
|
Task UpdateChecker = new Task(() => Checker.PingUpdateServer());
|
||||||
|
UpdateChecker.Start();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Reload = new ReloadPatch();
|
// Reload = new ReloadPatch();
|
||||||
//Patching goes here
|
//Patching goes here
|
||||||
|
|
||||||
@@ -141,6 +157,8 @@ namespace SeamlessClientPlugin
|
|||||||
//throw new NotImplementedException();
|
//throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void PingTimer_Elapsed(object sender, ElapsedEventArgs e)
|
private void PingTimer_Elapsed(object sender, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
//TryShow("Sending PluginVersion to Server!");
|
//TryShow("Sending PluginVersion to Server!");
|
||||||
@@ -148,7 +166,7 @@ namespace SeamlessClientPlugin
|
|||||||
{
|
{
|
||||||
|
|
||||||
ClientMessage PingServer = new ClientMessage(ClientMessageType.FirstJoin);
|
ClientMessage PingServer = new ClientMessage(ClientMessageType.FirstJoin);
|
||||||
MyAPIGateway.Multiplayer.SendMessageToServer(SeamlessClientNetID, Utilities.Utility.Serialize(PingServer));
|
MyAPIGateway.Multiplayer?.SendMessageToServer(SeamlessClientNetID, Utilities.Utility.Serialize(PingServer));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -222,5 +240,38 @@ namespace SeamlessClientPlugin
|
|||||||
|
|
||||||
MyLog.Default?.WriteLineAndConsole($"SeamlessClient: {message}");
|
MyLog.Default?.WriteLineAndConsole($"SeamlessClient: {message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void RestartClientAfterUpdate()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TryShow("Restarting Client!");
|
||||||
|
|
||||||
|
string exe = Assembly.GetEntryAssembly().Location;
|
||||||
|
|
||||||
|
|
||||||
|
Process currentProcess = Process.GetCurrentProcess();
|
||||||
|
|
||||||
|
string[] CommandArgs = Environment.GetCommandLineArgs();
|
||||||
|
|
||||||
|
string NewCommandLine = "";
|
||||||
|
for(int i = 1; i < CommandArgs.Length; i++)
|
||||||
|
{
|
||||||
|
NewCommandLine += " "+ CommandArgs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
TryShow(NewCommandLine);
|
||||||
|
|
||||||
|
Process.Start(exe, NewCommandLine);
|
||||||
|
|
||||||
|
|
||||||
|
currentProcess.Kill();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
TryShow("Restarting Client error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -84,9 +84,21 @@
|
|||||||
<Reference Include="System.Core">
|
<Reference Include="System.Core">
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\Nexus\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.Compression.FileSystem" />
|
||||||
|
<Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\Nexus\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System.Runtime.InteropServices.RuntimeInformation">
|
<Reference Include="System.Runtime.InteropServices.RuntimeInformation">
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
<Reference Include="System.Xml.Linq">
|
<Reference Include="System.Xml.Linq">
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
@@ -149,6 +161,7 @@
|
|||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="SeamlessTransfer\LoadServer.cs" />
|
<Compile Include="SeamlessTransfer\LoadServer.cs" />
|
||||||
<Compile Include="SeamlessTransfer\Transfer.cs" />
|
<Compile Include="SeamlessTransfer\Transfer.cs" />
|
||||||
|
<Compile Include="Updater\UpdateChecker.cs" />
|
||||||
<Compile Include="Utilities\Utility.cs" />
|
<Compile Include="Utilities\Utility.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
using Sandbox;
|
using Sandbox;
|
||||||
using Sandbox.Definitions;
|
using Sandbox.Definitions;
|
||||||
using Sandbox.Engine;
|
using Sandbox.Engine;
|
||||||
|
using Sandbox.Engine.Analytics;
|
||||||
using Sandbox.Engine.Multiplayer;
|
using Sandbox.Engine.Multiplayer;
|
||||||
using Sandbox.Engine.Networking;
|
using Sandbox.Engine.Networking;
|
||||||
using Sandbox.Engine.Physics;
|
using Sandbox.Engine.Physics;
|
||||||
@@ -21,6 +22,7 @@ using SeamlessClientPlugin.Utilities;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
@@ -28,6 +30,7 @@ using System.Text;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using VRage;
|
using VRage;
|
||||||
|
using VRage.FileSystem;
|
||||||
using VRage.Game;
|
using VRage.Game;
|
||||||
using VRage.Game.ModAPI;
|
using VRage.Game.ModAPI;
|
||||||
using VRage.Game.SessionComponents;
|
using VRage.Game.SessionComponents;
|
||||||
@@ -68,6 +71,7 @@ namespace SeamlessClientPlugin.SeamlessTransfer
|
|||||||
//Reflected Methods
|
//Reflected Methods
|
||||||
public static FieldInfo VirtualClients;
|
public static FieldInfo VirtualClients;
|
||||||
public static FieldInfo AdminSettings;
|
public static FieldInfo AdminSettings;
|
||||||
|
|
||||||
public static FieldInfo RemoteAdminSettings;
|
public static FieldInfo RemoteAdminSettings;
|
||||||
public static FieldInfo MPlayerGPSCollection;
|
public static FieldInfo MPlayerGPSCollection;
|
||||||
public static MethodInfo RemovePlayerFromDictionary;
|
public static MethodInfo RemovePlayerFromDictionary;
|
||||||
@@ -75,6 +79,8 @@ namespace SeamlessClientPlugin.SeamlessTransfer
|
|||||||
public static MethodInfo LoadPlayerInternal;
|
public static MethodInfo LoadPlayerInternal;
|
||||||
public static MethodInfo LoadMembersFromWorld;
|
public static MethodInfo LoadMembersFromWorld;
|
||||||
|
|
||||||
|
public static MethodInfo LoadMultiplayer;
|
||||||
|
|
||||||
|
|
||||||
public LoadServer()
|
public LoadServer()
|
||||||
{
|
{
|
||||||
@@ -131,6 +137,12 @@ namespace SeamlessClientPlugin.SeamlessTransfer
|
|||||||
AdminSettings = typeof(MySession).GetField("m_adminSettings", BindingFlags.Instance | BindingFlags.NonPublic);
|
AdminSettings = typeof(MySession).GetField("m_adminSettings", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
RemoteAdminSettings = typeof(MySession).GetField("m_remoteAdminSettings", BindingFlags.Instance | BindingFlags.NonPublic);
|
RemoteAdminSettings = typeof(MySession).GetField("m_remoteAdminSettings", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
MPlayerGPSCollection = typeof(MyPlayerCollection).GetField("m_players", BindingFlags.Instance | BindingFlags.NonPublic);
|
MPlayerGPSCollection = typeof(MyPlayerCollection).GetField("m_players", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
LoadMultiplayer = typeof(MySession).GetMethod("LoadMultiplayer", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
|
||||||
|
|
||||||
|
MethodInfo LoadingAction = typeof(MySessionLoader).GetMethod("LoadMultiplayerSession", BindingFlags.Public | BindingFlags.Static);
|
||||||
|
Patcher.Patch(LoadingAction, prefix: new HarmonyMethod(GetPatchMethod(nameof(LoadMultiplayerSession))));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -140,6 +152,101 @@ namespace SeamlessClientPlugin.SeamlessTransfer
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static bool GetCustomLoadingScreenPath(List<MyObjectBuilder_Checkpoint.ModItem> Mods, out string File)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
string WorkshopDir = MyFileSystem.ModsPath;
|
||||||
|
|
||||||
|
SeamlessClient.TryShow(WorkshopDir);
|
||||||
|
|
||||||
|
|
||||||
|
File = null;
|
||||||
|
SeamlessClient.TryShow("Installed Mods: " + Mods);
|
||||||
|
foreach(var Mod in Mods)
|
||||||
|
{
|
||||||
|
string SearchDir = Mod.GetPath();
|
||||||
|
var files = Directory.EnumerateFiles(SearchDir, "*.dds", SearchOption.TopDirectoryOnly);
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
if (Path.GetFileNameWithoutExtension(file) == "CustomLoadingBackground")
|
||||||
|
{
|
||||||
|
SeamlessClient.TryShow(Mod.FriendlyName + " contains a custom loading background!");
|
||||||
|
File = file;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SeamlessClient.TryShow("No installed custom loading screen!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static bool LoadMultiplayerSession(MyObjectBuilder_World world, MyMultiplayerBase multiplayerSession)
|
||||||
|
{
|
||||||
|
MyLog.Default.WriteLine("LoadSession() - Start");
|
||||||
|
if (!MyWorkshop.CheckLocalModsAllowed(world.Checkpoint.Mods, allowLocalMods: false))
|
||||||
|
{
|
||||||
|
MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Error, MyMessageBoxButtonsType.OK, messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionError), messageText: MyTexts.Get(MyCommonTexts.DialogTextLocalModsDisabledInMultiplayer)));
|
||||||
|
MyLog.Default.WriteLine("LoadSession() - End");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
MyWorkshop.DownloadModsAsync(world.Checkpoint.Mods, delegate (bool success)
|
||||||
|
{
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
MyScreenManager.CloseAllScreensNowExcept(null);
|
||||||
|
MyGuiSandbox.Update(16);
|
||||||
|
if (MySession.Static != null)
|
||||||
|
{
|
||||||
|
MySession.Static.Unload();
|
||||||
|
MySession.Static = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string CustomBackgroundImage = null;
|
||||||
|
GetCustomLoadingScreenPath(world.Checkpoint.Mods, out CustomBackgroundImage);
|
||||||
|
|
||||||
|
MySessionLoader.StartLoading(delegate
|
||||||
|
{
|
||||||
|
|
||||||
|
LoadMultiplayer.Invoke(null, new object[] { world, multiplayerSession });
|
||||||
|
//MySession.LoadMultiplayer(world, multiplayerSession);
|
||||||
|
}, null, CustomBackgroundImage, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
multiplayerSession.Dispose();
|
||||||
|
MySessionLoader.UnloadAndExitToMenu();
|
||||||
|
if (MyGameService.IsOnline)
|
||||||
|
{
|
||||||
|
MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Error, MyMessageBoxButtonsType.OK, messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionError), messageText: MyTexts.Get(MyCommonTexts.DialogTextDownloadModsFailed)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Error, MyMessageBoxButtonsType.OK, messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionError), messageText: new StringBuilder(string.Format(MyTexts.GetString(MyCommonTexts.DialogTextDownloadModsFailedSteamOffline), MySession.GameServiceName))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyLog.Default.WriteLine("LoadSession() - End");
|
||||||
|
}, delegate
|
||||||
|
{
|
||||||
|
multiplayerSession.Dispose();
|
||||||
|
MySessionLoader.UnloadAndExitToMenu();
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static void OnUserJoined(ref JoinResultMsg msg)
|
private static void OnUserJoined(ref JoinResultMsg msg)
|
||||||
{
|
{
|
||||||
if (SeamlessClient.IsSwitching && msg.JoinResult == JoinResult.OK)
|
if (SeamlessClient.IsSwitching && msg.JoinResult == JoinResult.OK)
|
||||||
@@ -317,48 +424,19 @@ namespace SeamlessClientPlugin.SeamlessTransfer
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
foreach(var GPS in checkpoint.Gps.Dictionary)
|
|
||||||
{
|
|
||||||
if (GPS.Key != MySession.Static.LocalPlayerId)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
SeamlessClient.TryShow(GPS.Key + ":" + GPS.Value.Entries.Count);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SeamlessClient.TryShow("LocalPlayerID: " + MySession.Static.LocalPlayerId);
|
SeamlessClient.TryShow("LocalPlayerID: " + MySession.Static.LocalPlayerId);
|
||||||
checkpoint.Gps.Dictionary.TryGetValue(MySession.Static.LocalPlayerId, out MyObjectBuilder_Gps GPSCollection);
|
//checkpoint.Gps.Dictionary.TryGetValue(MySession.Static.LocalPlayerId, out MyObjectBuilder_Gps GPSCollection);
|
||||||
SeamlessClient.TryShow("You have " + GPSCollection.Entries.Count + " gps points!");
|
//SeamlessClient.TryShow("You have " + GPSCollection.Entries.Count + " gps points!");
|
||||||
|
|
||||||
|
|
||||||
Dictionary<long, Dictionary<int, MyGps>> m_playerGpss = (Dictionary<long, Dictionary<int, MyGps>>)typeof(MyGpsCollection).GetField("m_playerGpss", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(MySession.Static.Gpss);
|
|
||||||
m_playerGpss.Clear();
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var GPS in GPSCollection.Entries)
|
|
||||||
{
|
|
||||||
MyGps myGps = new MyGps(GPS);
|
|
||||||
|
|
||||||
if(MySession.Static.Gpss.AddPlayerGps(MySession.Static.LocalPlayerId, ref myGps))
|
|
||||||
{
|
|
||||||
MyHud.GpsMarkers.RegisterMarker(myGps);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SeamlessClient.TryShow("Failed to registered Marker! It already exsists!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MySession.Static.Gpss = new MyGpsCollection();
|
||||||
MySession.Static.Gpss.LoadGpss(checkpoint);
|
MySession.Static.Gpss.LoadGpss(checkpoint);
|
||||||
MySession.Static.Toolbars.LoadToolbars(checkpoint);
|
MyRenderProxy.RebuildCullingStructure();
|
||||||
|
//MySession.Static.Toolbars.LoadToolbars(checkpoint);
|
||||||
|
|
||||||
Sync.Players.RespawnComponent.InitFromCheckpoint(checkpoint);
|
Sync.Players.RespawnComponent.InitFromCheckpoint(checkpoint);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -124,7 +124,12 @@ namespace SeamlessClientPlugin.SeamlessTransfer
|
|||||||
//Sync.Clients.Clear();
|
//Sync.Clients.Clear();
|
||||||
|
|
||||||
|
|
||||||
|
var PCollection = MySession.Static.Gpss[MySession.Static.LocalPlayerId];
|
||||||
|
PCollection.Clear();
|
||||||
|
MyHud.GpsMarkers.Clear();
|
||||||
|
|
||||||
|
|
||||||
|
SeamlessClient.TryShow(PCollection.Count + "registered GPS points");
|
||||||
// MyGuiSandbox.UnloadContent();
|
// MyGuiSandbox.UnloadContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
300
Updater/UpdateChecker.cs
Normal file
300
Updater/UpdateChecker.cs
Normal file
@@ -0,0 +1,300 @@
|
|||||||
|
using ProtoBuf;
|
||||||
|
using Sandbox.Graphics.GUI;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace SeamlessClientPlugin.Updater
|
||||||
|
{
|
||||||
|
public class UpdateChecker
|
||||||
|
{
|
||||||
|
public string PluginFolder;
|
||||||
|
public string CurrentVersion;
|
||||||
|
public bool DownloadUpdate;
|
||||||
|
|
||||||
|
const int PORT_NO = 27010;
|
||||||
|
//AWS Website server
|
||||||
|
const string SERVER_IP = "3.80.137.183";
|
||||||
|
|
||||||
|
private byte[] RecievedZipMememory;
|
||||||
|
|
||||||
|
public UpdateChecker(string Version, bool AutoUpdate)
|
||||||
|
{
|
||||||
|
this.DownloadUpdate = AutoUpdate;
|
||||||
|
PluginFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||||
|
CurrentVersion = Version;
|
||||||
|
|
||||||
|
SeamlessClient.TryShow("You are running @" + PluginFolder);
|
||||||
|
DeleteOLDFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void PingUpdateServer()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
TcpClient client = new TcpClient(SERVER_IP, PORT_NO);
|
||||||
|
client.ReceiveBufferSize = 1000000;
|
||||||
|
|
||||||
|
NetworkStream nwStream = client.GetStream();
|
||||||
|
|
||||||
|
UpdateMessage Message = new UpdateMessage();
|
||||||
|
Message.ClientVersion = CurrentVersion;
|
||||||
|
Message.DownloadNewUpdate = DownloadUpdate;
|
||||||
|
|
||||||
|
//Send current version to server
|
||||||
|
//string XMLData = Utility.Serialize(Message);
|
||||||
|
byte[] bytesToSend = Utility.Serialize(Message);
|
||||||
|
nwStream.Write(bytesToSend, 0, bytesToSend.Length);
|
||||||
|
|
||||||
|
//Get server reply
|
||||||
|
byte[] bytesToRead = new byte[client.ReceiveBufferSize];
|
||||||
|
int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);
|
||||||
|
|
||||||
|
|
||||||
|
byte[] ReMessage = bytesToRead.Take(bytesRead).ToArray();
|
||||||
|
//string StringServerReply = Encoding.ASCII.GetString(bytesToRead, 0, bytesRead);
|
||||||
|
// SeamlessClient.TryShow(StringServerReply);
|
||||||
|
|
||||||
|
|
||||||
|
Message = Utility.Deserialize<UpdateMessage>(ReMessage);
|
||||||
|
UpdateServerReply(Message);
|
||||||
|
|
||||||
|
SeamlessClient.TryShow("Received! Latest Version: " + Message.ServerVersion);
|
||||||
|
}catch(SocketException)
|
||||||
|
{
|
||||||
|
//Cant connect to server.
|
||||||
|
SeamlessClient.TryShow("Cant Connect to UpdateServer!");
|
||||||
|
return;
|
||||||
|
}catch(Exception ex)
|
||||||
|
{
|
||||||
|
SeamlessClient.TryShow("Update Error! \n"+ex.ToString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateServerReply(UpdateMessage Message)
|
||||||
|
{
|
||||||
|
if (!NeedsUpdate(Message.ClientVersion, Message.ServerVersion))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SeamlessClient.TryShow("An Update is required! ClientVersion: [" + Message.ClientVersion + "] Server Version: [" + Message.ServerVersion + "]");
|
||||||
|
RecievedZipMememory = Message.XmlCharactersAsBytes;
|
||||||
|
|
||||||
|
|
||||||
|
if (!DownloadUpdate)
|
||||||
|
{
|
||||||
|
//Create Update question and UI
|
||||||
|
StringBuilder Title = new StringBuilder();
|
||||||
|
Title.Append($"Would you like to download Seamless Client Plugin {Message.ServerVersion} Update?");
|
||||||
|
StringBuilder Caption = new StringBuilder();
|
||||||
|
Caption.AppendLine(" - Patch Notes - ");
|
||||||
|
Caption.AppendLine();
|
||||||
|
Caption.AppendLine(Message.UpdateNotes);
|
||||||
|
Caption.AppendLine();
|
||||||
|
Caption.AppendLine("Your client will restart after install");
|
||||||
|
|
||||||
|
|
||||||
|
MyScreenManager.AddScreen(MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Info, MyMessageBoxButtonsType.YES_NO_TIMEOUT, Caption, Title, null, null, null, null, UpdateMessageBoxCallback, 60000, MyGuiScreenMessageBox.ResultEnum.YES, canHideOthers: true, new VRageMath.Vector2(.5f,.4f), useOpacity: false));
|
||||||
|
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExtractAndReplace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void UpdateMessageBoxCallback(MyGuiScreenMessageBox.ResultEnum Result)
|
||||||
|
{
|
||||||
|
//Update chcker
|
||||||
|
if (Result == MyGuiScreenMessageBox.ResultEnum.YES)
|
||||||
|
{
|
||||||
|
SeamlessClient.TryShow("Clicked Yes");
|
||||||
|
//If they clicked yes, ping the update server again and request new file
|
||||||
|
DownloadUpdate = true;
|
||||||
|
PingUpdateServer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Result == MyGuiScreenMessageBox.ResultEnum.NO || Result == MyGuiScreenMessageBox.ResultEnum.CANCEL)
|
||||||
|
{
|
||||||
|
//Return. (Do not update)
|
||||||
|
SeamlessClient.TryShow("Clicked No or Cancel");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void DeleteOLDFiles()
|
||||||
|
{
|
||||||
|
foreach(var OLDFile in Directory.GetFiles(PluginFolder, "*.old"))
|
||||||
|
{
|
||||||
|
File.Delete(OLDFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
SeamlessClient.TryShow("Deleted all OLD update files");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ExtractAndReplace()
|
||||||
|
{
|
||||||
|
//save latest zip in dir
|
||||||
|
string ZipPath = Path.Combine(PluginFolder, "Latest.zip");
|
||||||
|
File.WriteAllBytes(ZipPath, RecievedZipMememory);
|
||||||
|
|
||||||
|
|
||||||
|
//Start extractor
|
||||||
|
using (ZipArchive archive = ZipFile.OpenRead(ZipPath))
|
||||||
|
{
|
||||||
|
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||||
|
{
|
||||||
|
string ExsistingFilePath = Path.Combine(PluginFolder, entry.Name);
|
||||||
|
string OldFilePath = Path.Combine(PluginFolder, entry.Name+".old");
|
||||||
|
SeamlessClient.TryShow(ExsistingFilePath + "=>" + OldFilePath);
|
||||||
|
|
||||||
|
|
||||||
|
if (File.Exists(OldFilePath))
|
||||||
|
File.Delete(OldFilePath);
|
||||||
|
|
||||||
|
File.Move(ExsistingFilePath, OldFilePath);
|
||||||
|
entry.ExtractToFile(ExsistingFilePath, true);
|
||||||
|
//File.Delete(OldFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Delete latest zip
|
||||||
|
File.Delete(ZipPath);
|
||||||
|
|
||||||
|
//Restart client
|
||||||
|
SeamlessClient.TryShow("UpdateComplete!");
|
||||||
|
SeamlessClient.RestartClientAfterUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool NeedsUpdate(string ClientVersion, string ServerVersion)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Version Client = new Version(ClientVersion);
|
||||||
|
Version Latest = new Version(ServerVersion);
|
||||||
|
|
||||||
|
var result = Client.CompareTo(Latest);
|
||||||
|
if (result > 0)
|
||||||
|
{
|
||||||
|
//Console.WriteLine("Client is greater");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (result < 0)
|
||||||
|
{
|
||||||
|
//Console.WriteLine("Latest is greater");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Console.WriteLine("versions are equal");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public class UpdateMessage
|
||||||
|
{
|
||||||
|
[ProtoMember(10)]
|
||||||
|
public string ClientVersion = "";
|
||||||
|
|
||||||
|
[ProtoMember(20)]
|
||||||
|
public bool UpToDate = false;
|
||||||
|
|
||||||
|
[ProtoMember(30)]
|
||||||
|
public bool DownloadNewUpdate = false;
|
||||||
|
|
||||||
|
[ProtoMember(40)]
|
||||||
|
public string ServerVersion = "";
|
||||||
|
|
||||||
|
[ProtoMember(50)]
|
||||||
|
public string UpdateNotes = "";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Misc Stuff incase I need it */
|
||||||
|
[ProtoMember(60)]
|
||||||
|
public byte[] XmlCharactersAsBytes;
|
||||||
|
|
||||||
|
|
||||||
|
public UpdateMessage() { }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Utility
|
||||||
|
{
|
||||||
|
public static string SerializeObject<T>(this T toSerialize)
|
||||||
|
{
|
||||||
|
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
|
||||||
|
|
||||||
|
using (StringWriter textWriter = new StringWriter())
|
||||||
|
{
|
||||||
|
xmlSerializer.Serialize(textWriter, toSerialize);
|
||||||
|
return textWriter.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static T XmlDeserialize<T>(this string toDeserialize)
|
||||||
|
{
|
||||||
|
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
|
||||||
|
using (StringReader textReader = new StringReader(toDeserialize))
|
||||||
|
{
|
||||||
|
return (T)xmlSerializer.Deserialize(textReader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static byte[] Serialize<T>(T instance)
|
||||||
|
{
|
||||||
|
if (instance == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
|
||||||
|
using (var m = new MemoryStream())
|
||||||
|
{
|
||||||
|
// m.Seek(0, SeekOrigin.Begin);
|
||||||
|
Serializer.Serialize(m, instance);
|
||||||
|
|
||||||
|
return m.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T Deserialize<T>(byte[] data)
|
||||||
|
{
|
||||||
|
if (data == null)
|
||||||
|
return default;
|
||||||
|
|
||||||
|
using (var m = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
return Serializer.Deserialize<T>(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,4 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Lib.Harmony" version="2.0.4" targetFramework="net472" />
|
<package id="Lib.Harmony" version="2.0.4" targetFramework="net472" />
|
||||||
|
<package id="System.IO.Compression" version="4.3.0" targetFramework="net472" />
|
||||||
|
<package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net472" />
|
||||||
</packages>
|
</packages>
|
Reference in New Issue
Block a user