Re-vamed updater to fix issues and acutally pull from github instead.

Added little popup warning screen when switching servers
This commit is contained in:
Bob Da Ross
2021-03-22 23:08:11 -05:00
parent 6ee6f7b170
commit fa064dd324
5 changed files with 217 additions and 114 deletions

View File

@@ -22,6 +22,7 @@ using System.Windows.Forms;
using VRage.Input; using VRage.Input;
using VRage.Plugins; using VRage.Plugins;
using VRage.Utils; using VRage.Utils;
using VRageMath;
using VRageRender; using VRageRender;
namespace SeamlessClientPlugin namespace SeamlessClientPlugin
@@ -106,7 +107,7 @@ namespace SeamlessClientPlugin
public static string Version = "1.2.0"; public static string Version = "1.2.10";
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;
@@ -118,6 +119,8 @@ namespace SeamlessClientPlugin
public static bool IsSwitching = false; public static bool IsSwitching = false;
public static bool RanJoin = false; public static bool RanJoin = false;
public static Action JoinAction = () => { }; public static Action JoinAction = () => { };
@@ -136,8 +139,7 @@ namespace SeamlessClientPlugin
{ {
TryShow("Running Seamless Client Plugin v[" + Version + "]"); TryShow("Running Seamless Client Plugin v[" + Version + "]");
UpdateChecker Checker = new UpdateChecker(Version, false); UpdateChecker Checker = new UpdateChecker(false);
Task UpdateChecker = new Task(() => Checker.PingUpdateServer()); Task UpdateChecker = new Task(() => Checker.PingUpdateServer());
UpdateChecker.Start(); UpdateChecker.Start();
@@ -145,9 +147,6 @@ namespace SeamlessClientPlugin
// Reload = new ReloadPatch(); // Reload = new ReloadPatch();
//Patching goes here //Patching goes here
@@ -165,8 +164,14 @@ namespace SeamlessClientPlugin
try try
{ {
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)
{ {
@@ -185,6 +190,7 @@ namespace SeamlessClientPlugin
TryShow("Initilizing Communications!"); TryShow("Initilizing Communications!");
RunInitilizations(); RunInitilizations();
Initilized = true; Initilized = true;
} }
//OnNewPlayerRequest //OnNewPlayerRequest
//throw new NotImplementedException(); //throw new NotImplementedException();

View File

@@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SeamlessClientPlugin</RootNamespace> <RootNamespace>SeamlessClientPlugin</RootNamespace>
<AssemblyName>SeamlessClientPlugin</AssemblyName> <AssemblyName>SeamlessClientPlugin</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic> <Deterministic>true</Deterministic>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
@@ -41,6 +41,9 @@
<Reference Include="0Harmony, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="0Harmony, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\Nexus\packages\Lib.Harmony.2.0.4\lib\net472\0Harmony.dll</HintPath> <HintPath>..\Nexus\packages\Lib.Harmony.2.0.4\lib\net472\0Harmony.dll</HintPath>
</Reference> </Reference>
<Reference Include="AutoUpdater.NET, Version=1.6.4.0, Culture=neutral, PublicKeyToken=501435c91b35f4bc, processorArchitecture=MSIL">
<HintPath>packages\Autoupdater.NET.Official.1.6.4\lib\net45\AutoUpdater.NET.dll</HintPath>
</Reference>
<Reference Include="NLog"> <Reference Include="NLog">
<HintPath>..\..\..\Desktop\TorchServers\torch-server\NLog.dll</HintPath> <HintPath>..\..\..\Desktop\TorchServers\torch-server\NLog.dll</HintPath>
<Private>False</Private> <Private>False</Private>
@@ -98,7 +101,10 @@
<Reference Include="System.Runtime.InteropServices.RuntimeInformation"> <Reference Include="System.Runtime.InteropServices.RuntimeInformation">
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Runtime.Serialization.Json" />
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq"> <Reference Include="System.Xml.Linq">
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>

View File

@@ -7,6 +7,7 @@ using Sandbox.Game.Gui;
using Sandbox.Game.Multiplayer; using Sandbox.Game.Multiplayer;
using Sandbox.Game.World; using Sandbox.Game.World;
using Sandbox.Graphics.GUI; using Sandbox.Graphics.GUI;
using Sandbox.ModAPI;
using SeamlessClientPlugin.ClientMessages; using SeamlessClientPlugin.ClientMessages;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -86,18 +87,30 @@ namespace SeamlessClientPlugin.SeamlessTransfer
private void MyGameService_OnPingServerResponded(object sender, MyGameServerItem e) private void MyGameService_OnPingServerResponded(object sender, MyGameServerItem e)
{ {
MyGameService.OnPingServerResponded -= MyGameService_OnPingServerResponded; MyGameService.OnPingServerResponded -= MyGameService_OnPingServerResponded;
MyGameService.OnPingServerFailedToRespond -= MyGameService_OnPingServerFailedToRespond; MyGameService.OnPingServerFailedToRespond -= MyGameService_OnPingServerFailedToRespond;
SeamlessClient.TryShow("ServerPing Successful! Attempting to connect to lobby: " + e.GameID); SeamlessClient.TryShow("ServerPing Successful! Attempting to connect to lobby: " + e.GameID);
LoadServer.LoadWorldData(e, WorldRequest.DeserializeWorldData()); LoadServer.LoadWorldData(e, WorldRequest.DeserializeWorldData());
MySandboxGame.Static.Invoke(delegate MySandboxGame.Static.Invoke(delegate
{ {
StringBuilder Builder = new StringBuilder();
Builder.AppendLine("Please be patient! Some users can spend a minute switching servers... others may be able to swtich faster. Lots of factors to consider.");
Builder.AppendLine();
Builder.AppendLine("Sitting in spectator is perfectly normal for a few seconds!");
MyAPIGateway.Utilities.ShowMissionScreen("Switching Servers!",null, null, Builder.ToString(), null, "Ok!");
//MySessionLoader.UnloadAndExitToMenu(); //MySessionLoader.UnloadAndExitToMenu();
UnloadCurrentServer(); UnloadCurrentServer();
//MyJoinGameHelper.JoinGame(e, true); //MyJoinGameHelper.JoinGame(e, true);
LoadServer.ResetMPClient(); LoadServer.ResetMPClient();
ClearEntities(); ClearEntities();
//ReloadPatch.SeamlessSwitch = false; //ReloadPatch.SeamlessSwitch = false;
}, "SeamlessClient"); }, "SeamlessClient");

View File

@@ -1,14 +1,19 @@
using ProtoBuf; using AutoUpdaterDotNET;
using ProtoBuf;
using Sandbox.Graphics.GUI; using Sandbox.Graphics.GUI;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Linq; using System.Linq;
using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Reflection; using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization; using System.Xml.Serialization;
namespace SeamlessClientPlugin.Updater namespace SeamlessClientPlugin.Updater
@@ -23,128 +28,147 @@ namespace SeamlessClientPlugin.Updater
//AWS Website server //AWS Website server
const string SERVER_IP = "3.80.137.183"; const string SERVER_IP = "3.80.137.183";
private string GitHubAPILink = "https://api.github.com/repos/Casimir255/SeamlessClientPlugin/releases/latest";
private string GitHubZipLink;
private WebClient Client;
private byte[] RecievedZipMememory; 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);
public UpdateChecker(bool AutoUpdate)
{
PluginFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Client = new WebClient();
DeleteOLDFiles(); DeleteOLDFiles();
} }
public void PingUpdateServer() public void PingUpdateServer()
{ {
try try
{ {
//Create new webclient and insert a user-agent
Client.Headers["User-Agent"] = "SeamlessClientUpdater";
TcpClient client = new TcpClient(SERVER_IP, PORT_NO); //Grap API data for latest seamless client release
client.ReceiveBufferSize = 1000000; string data = Client.DownloadString(GitHubAPILink);
NetworkStream nwStream = client.GetStream(); //SeamlessClient.TryShow(data);
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(); DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(GithubRelease));
//string StringServerReply = Encoding.ASCII.GetString(bytesToRead, 0, bytesRead);
// SeamlessClient.TryShow(StringServerReply);
GithubRelease Release;
Message = Utility.Deserialize<UpdateMessage>(ReMessage); using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(data)))
UpdateServerReply(Message);
SeamlessClient.TryShow("Received! Latest Version: " + Message.ServerVersion);
}catch(SocketException)
{ {
//Cant connect to server. Release = (GithubRelease)s.ReadObject(stream);
SeamlessClient.TryShow("Cant Connect to UpdateServer!"); }
if (Release == null || !TryGetMainRelease(Release.Content, out GitZipFile MainReleaseFile))
return; return;
}catch(Exception ex)
//Check if the client needs an update based off of github latest release version
if (!NeedsUpdate(SeamlessClient.Version, Release.LatestVersion))
return;
//Ask client if they want to update!
ShowDialog(Release, MainReleaseFile);
}
catch (Exception Ex)
{ {
SeamlessClient.TryShow("Update Error! \n"+ex.ToString()); SeamlessClient.TryShow(Ex.ToString());
return; }
}
private bool TryGetMainRelease(GitZipFile[] Files, out GitZipFile Release)
{
Release = null;
//Sanity saftey checks
if (Files == null || Files.Length <= 0)
return false;
foreach (GitZipFile File in Files)
{
if (File.Name == "SeamlessClientPlugin.zip")
{
Release = File;
return true;
} }
} }
private void UpdateServerReply(UpdateMessage Message) return false;
}
private void ShowDialog(GithubRelease Release, GitZipFile MainReleaseFile)
{ {
if (!NeedsUpdate(Message.ClientVersion, Message.ServerVersion)) StringBuilder Response = new StringBuilder();
return; Response.AppendLine($"Current version: {SeamlessClient.Version} Latest: {Release.LatestVersion}");
Response.AppendLine($"Update: {Release.Name}");
Response.AppendLine($"Description: {Release.Description}");
Response.AppendLine($"Size: {MainReleaseFile.Size / 1000}kb");
Response.AppendLine();
Response.AppendLine("Warning: If you have a version less than latest seamless will be disabled to prevent crashes!");
Response.AppendLine("(Clicking yes should restart your game)");
SeamlessClient.TryShow("An Update is required! ClientVersion: [" + Message.ClientVersion + "] Server Version: [" + Message.ServerVersion + "]"); DialogResult Result = MessageBox.Show(Response.ToString(), $"Download Seamless Client Plugin Update v{ Release.LatestVersion}?", MessageBoxButtons.YesNo, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
RecievedZipMememory = Message.XmlCharactersAsBytes; SeamlessClient.TryShow(Response.ToString());
if (Result == DialogResult.Yes)
if (!DownloadUpdate)
{ {
//Create Update question and UI SeamlessClient.TryShow("Client wants to update!");
StringBuilder Title = new StringBuilder(); string DownloadPath = Path.Combine(PluginFolder, MainReleaseFile.Name);
Title.Append($"Would you like to download Seamless Client Plugin {Message.ServerVersion} Update?"); Client.DownloadFile(new Uri(MainReleaseFile.ZipURL), DownloadPath);
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));
if (!File.Exists(DownloadPath))
{
SeamlessClient.TryShow("Failed to download zip!");
return; return;
} }
if (ExtractAndReplace(DownloadPath))
{
StringBuilder ErrorResponse = new StringBuilder();
ErrorResponse.AppendLine("There was an error during the extraction proccess! Check your logs for more information!");
ErrorResponse.AppendLine();
ErrorResponse.AppendLine("You can download manually here:");
ErrorResponse.AppendLine(Release.GitHubPage);
SeamlessClient.TryShow(ErrorResponse.ToString());
MessageBox.Show(ErrorResponse.ToString(), $"Failed to update plugin to v{ Release.LatestVersion}!", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
return;
}
}
else else
{ {
ExtractAndReplace(); SeamlessClient.TryShow("Client skipped Update!");
}
}
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; return;
} }
if (Result == MyGuiScreenMessageBox.ResultEnum.NO || Result == MyGuiScreenMessageBox.ResultEnum.CANCEL)
{
//Return. (Do not update)
SeamlessClient.TryShow("Clicked No or Cancel");
return;
}
} }
private void DeleteOLDFiles() private void DeleteOLDFiles()
{ {
foreach(var OLDFile in Directory.GetFiles(PluginFolder, "*.old")) foreach (var OLDFile in Directory.GetFiles(PluginFolder, "*.old"))
{ {
File.Delete(OLDFile); File.Delete(OLDFile);
} }
@@ -154,12 +178,10 @@ namespace SeamlessClientPlugin.Updater
} }
private void ExtractAndReplace() private bool ExtractAndReplace(string ZipPath)
{
try
{ {
//save latest zip in dir
string ZipPath = Path.Combine(PluginFolder, "Latest.zip");
File.WriteAllBytes(ZipPath, RecievedZipMememory);
//Start extractor //Start extractor
using (ZipArchive archive = ZipFile.OpenRead(ZipPath)) using (ZipArchive archive = ZipFile.OpenRead(ZipPath))
@@ -167,15 +189,19 @@ namespace SeamlessClientPlugin.Updater
foreach (ZipArchiveEntry entry in archive.Entries) foreach (ZipArchiveEntry entry in archive.Entries)
{ {
string ExsistingFilePath = Path.Combine(PluginFolder, entry.Name); string ExsistingFilePath = Path.Combine(PluginFolder, entry.Name);
string OldFilePath = Path.Combine(PluginFolder, entry.Name+".old"); string OldFilePath = Path.Combine(PluginFolder, entry.Name + ".old");
SeamlessClient.TryShow(ExsistingFilePath + "=>" + OldFilePath);
//No need to extract to files that dont exsist
if (!File.Exists(ExsistingFilePath))
continue;
SeamlessClient.TryShow(ExsistingFilePath + "=>" + OldFilePath);
if (File.Exists(OldFilePath)) if (File.Exists(OldFilePath))
File.Delete(OldFilePath); File.Delete(OldFilePath);
File.Move(ExsistingFilePath, OldFilePath); File.Move(ExsistingFilePath, OldFilePath);
entry.ExtractToFile(ExsistingFilePath, true); entry.ExtractToFile(ExsistingFilePath, false);
//File.Delete(OldFilePath); //File.Delete(OldFilePath);
} }
} }
@@ -186,6 +212,14 @@ namespace SeamlessClientPlugin.Updater
//Restart client //Restart client
SeamlessClient.TryShow("UpdateComplete!"); SeamlessClient.TryShow("UpdateComplete!");
SeamlessClient.RestartClientAfterUpdate(); SeamlessClient.RestartClientAfterUpdate();
return true;
}
catch (Exception ex)
{
SeamlessClient.TryShow(ex.ToString());
return false;
}
} }
private bool NeedsUpdate(string ClientVersion, string ServerVersion) private bool NeedsUpdate(string ClientVersion, string ServerVersion)
@@ -199,16 +233,19 @@ namespace SeamlessClientPlugin.Updater
if (result > 0) if (result > 0)
{ {
//Console.WriteLine("Client is greater"); //Console.WriteLine("Client is greater");
SeamlessClient.TryShow("Client version is greater than latest! Wow!");
return false; return false;
} }
else if (result < 0) else if (result < 0)
{ {
//Console.WriteLine("Latest is greater"); //Console.WriteLine("Latest is greater");
SeamlessClient.TryShow("Client version is out-of-date!");
return true; return true;
} }
else else
{ {
//Console.WriteLine("versions are equal"); //Console.WriteLine("versions are equal");
SeamlessClient.TryShow("Client is up-to-date!");
return false; return false;
} }
} }
@@ -297,4 +334,44 @@ namespace SeamlessClientPlugin.Updater
} }
} }
[DataContract]
public class GithubRelease
{
[DataMember(Name = "url")]
public string GitHubPage { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "tag_name")]
public string LatestVersion { get; set; }
[DataMember(Name = "prerelease")]
public bool Beta { get; set; }
[DataMember(Name = "body")]
public string Description { get; set; }
[DataMember(Name = "assets")]
public GitZipFile[] Content { get; set; }
}
[DataContract]
public class GitZipFile
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "browser_download_url")]
public string ZipURL { get; set; }
[DataMember(Name = "size")]
public int Size { get; set; }
}
} }

View File

@@ -1,6 +1,7 @@
<?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="Autoupdater.NET.Official" version="1.6.4" targetFramework="net472" />
<package id="Lib.Harmony" version="2.0.4" targetFramework="net472" requireReinstallation="true" />
<package id="System.IO.Compression" version="4.3.0" 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" /> <package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net472" />
</packages> </packages>