private void MyMultiplayerClient_ClientLeft(ulong user, MyChatMemberStateChangeEnum stateChange) { if (user == base.ServerId) { base.RaiseHostLeft(); } else { if (this.m_members.Contains(user)) { this.m_members.Remove(user); string personaName = MyGameService.GetPersonaName(user); object[] objArray1 = new object[] { "Player disconnected: ", personaName, " (", user, ")" }; MySandboxGame.Log.WriteLineAndConsole(string.Concat(objArray1)); if (MySandboxGame.IsGameReady && (Sync.MyId != user)) { MyHudNotification notification = new MyHudNotification(MyCommonTexts.NotificationClientDisconnected, 0x1388, "Blue", MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, 0, MyNotificationLevel.Important); object[] arguments = new object[] { personaName }; notification.SetTextFormatArguments(arguments); MyHud.Notifications.Add(notification); } } this.m_memberData.Remove(user); } }
private void JoinServer(MyObjectBuilder_LastSession mySession) { try { MyGuiScreenProgress prog = new MyGuiScreenProgress(MyTexts.Get(MyCommonTexts.DialogTextCheckServerStatus)); MyGuiSandbox.AddScreen(prog); MyGameService.OnPingServerResponded += OnPingSuccess; MyGameService.OnPingServerFailedToRespond += OnPingFailure; MyGameService.PingServer(mySession.GetConnectionString()); void OnPingFailure(object sender, object data) { MyGuiSandbox.RemoveScreen(prog); MySandboxGame.Static.ServerFailedToRespond(sender, data); MyGameService.OnPingServerResponded -= OnPingSuccess; MyGameService.OnPingServerFailedToRespond -= OnPingFailure; } void OnPingSuccess(object sender, MyGameServerItem item) { MyGuiSandbox.RemoveScreen(prog); MySandboxGame.Static.ServerResponded(sender, item); MyGameService.OnPingServerResponded -= OnPingSuccess; MyGameService.OnPingServerFailedToRespond -= OnPingFailure; } } catch (Exception ex) { MyLog.Default.WriteLine(ex); MyGuiSandbox.Show(MyTexts.Get(MyCommonTexts.MultiplayerJoinIPError), MyCommonTexts.MessageBoxCaptionError); } }
public void SendPlayerData(string clientName) { uint num; uint num2; ConnectedClientDataMsg msg = new ConnectedClientDataMsg { SteamID = Sync.MyId, Name = clientName, Join = true, ExperimentalMode = this.ExperimentalMode }; byte[] buffer = new byte[0x400]; if (MyGameService.GetAuthSessionTicket(out num2, buffer, out num)) { msg.Token = new byte[num]; Array.Copy(buffer, msg.Token, (long)num); base.ReplicationLayer.SendClientConnected(ref msg); } else { MySessionLoader.UnloadAndExitToMenu(); StringBuilder messageCaption = MyTexts.Get(MyCommonTexts.MessageBoxCaptionError); MyStringId? okButtonText = null; okButtonText = null; okButtonText = null; okButtonText = null; Vector2?size = null; MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Error, MyMessageBoxButtonsType.OK, MyTexts.Get(MyCommonTexts.MultiplayerErrorConnectionFailed), messageCaption, okButtonText, okButtonText, okButtonText, okButtonText, null, 0, MyGuiScreenMessageBox.ResultEnum.YES, true, size)); } }
public static MyMultiplayerJoinResult JoinLobby(ulong lobbyId) { MyMultiplayerJoinResult ret = new MyMultiplayerJoinResult(); MyGameService.JoinLobby(lobbyId, delegate(bool success, IMyLobby lobby, MyLobbyEnterResponseEnum response) { if (!ret.Cancelled) { MyMultiplayerLobbyClient client2; if ((success && (response == MyLobbyEnterResponseEnum.Success)) && (lobby.OwnerId == Sync.MyId)) { response = MyLobbyEnterResponseEnum.DoesntExist; lobby.Leave(); } success &= response == MyLobbyEnterResponseEnum.Success; if (!success) { client2 = null; } else { MyMultiplayerLobbyClient client1 = new MyMultiplayerLobbyClient(lobby, new MySyncLayer(new MyTransportLayer(2))); Static = client1; client2 = client1; } ret.RaiseJoined(success, lobby, response, client2); } }); return(ret); }
public static MyMultiplayerHostResult HostLobby(MyLobbyType lobbyType, int maxPlayers, MySyncLayer syncLayer) { MyMultiplayerHostResult ret = new MyMultiplayerHostResult(); MyGameService.CreateLobby(lobbyType, (uint)maxPlayers, delegate(IMyLobby lobby, bool succes, string msg) { if (!ret.Cancelled) { if (succes && (lobby.OwnerId != Sync.MyId)) { succes = false; lobby.Leave(); } lobby.LobbyType = lobbyType; MyMultiplayerBase multiplayer = null; if (succes) { MyMultiplayerLobby lobby1 = new MyMultiplayerLobby(lobby, syncLayer); Static = lobby1; multiplayer = lobby1; multiplayer.ExperimentalMode = true; } ret.RaiseDone(succes, msg, multiplayer); } }); return(ret); }
public void Connect(string address) { MySessionLoader.UnloadAndExitToMenu(); MyGameService.OnPingServerResponded -= ServerResponded; MyGameService.OnPingServerFailedToRespond -= ServerFailedToRespond; MyGameService.OnPingServerResponded += ServerResponded; MyGameService.OnPingServerFailedToRespond += ServerFailedToRespond; MyGameService.PingServer(address); }
private void Destroy() { _game.Dispose(); _game = null; MyGameService.ShutDown(); _getVRagePluginList().Remove(_torch); MyInitializer.InvokeAfterRun(); }
//because KEEEN! public static string GetDefaultServiceName() { try { return(MyGameService.GetDefaultUGC().ServiceName); } catch { return(TorchBase.Instance.Config.UgcServiceType.ToString()); } }
public void Wait(bool runCallbacks = true) { while (!this.Cancelled && !this.m_done) { if (runCallbacks) { MyGameService.Update(); } Thread.Sleep(10); } }
private void Matchmaking_LobbyChatUpdate(IMyLobby lobby, ulong changedUser, ulong makingChangeUser, MyChatMemberStateChangeEnum stateChange) { if (lobby.LobbyId == this.m_lobby.LobbyId) { if (stateChange == MyChatMemberStateChangeEnum.Entered) { object[] objArray1 = new object[] { "Player entered: ", MyGameService.GetPersonaName(changedUser), " (", changedUser, ")" }; MySandboxGame.Log.WriteLineAndConsole(string.Concat(objArray1)); MyGameService.Peer2Peer.AcceptSession(changedUser); if ((Sync.Clients == null) || !Sync.Clients.HasClient(changedUser)) { base.RaiseClientJoined(changedUser); if (this.Scenario && (changedUser != Sync.MyId)) { base.SendAllMembersDataToClient(changedUser); } } if (MySandboxGame.IsGameReady && (changedUser != base.ServerId)) { MyHudNotification notification = new MyHudNotification(MyCommonTexts.NotificationClientConnected, 0x1388, "Blue", MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, 0, MyNotificationLevel.Important); object[] arguments = new object[] { MyGameService.GetPersonaName(changedUser) }; notification.SetTextFormatArguments(arguments); MyHud.Notifications.Add(notification); } } else { if ((Sync.Clients == null) || Sync.Clients.HasClient(changedUser)) { base.RaiseClientLeft(changedUser, stateChange); } if (changedUser == base.ServerId) { base.RaiseHostLeft(); MySessionLoader.UnloadAndExitToMenu(); StringBuilder messageCaption = MyTexts.Get(MyCommonTexts.MessageBoxCaptionError); MyStringId? okButtonText = null; okButtonText = null; okButtonText = null; okButtonText = null; Vector2?size = null; MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Error, MyMessageBoxButtonsType.OK, MyTexts.Get(MyCommonTexts.MultiplayerErrorServerHasLeft), messageCaption, okButtonText, okButtonText, okButtonText, okButtonText, null, 0, MyGuiScreenMessageBox.ResultEnum.YES, true, size)); } else if (MySandboxGame.IsGameReady) { MyHudNotification notification = new MyHudNotification(MyCommonTexts.NotificationClientDisconnected, 0x1388, "Blue", MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, 0, MyNotificationLevel.Important); object[] arguments = new object[] { MyGameService.GetPersonaName(changedUser) }; notification.SetTextFormatArguments(arguments); MyHud.Notifications.Add(notification); } } } }
private System.Threading.Tasks.Task <bool> ClearSteamCloud(string [] filesToDelete, bool force = false) { var Task = System.Threading.Tasks.Task <bool> .Factory.StartNew(() => { #if SE ulong totalBytes = 0; ulong availableBytes = 0; MyGameService.GetRemoteStorageQuota(out totalBytes, out availableBytes); MySandboxGame.Log.WriteLineAndConsole(string.Format("Quota: total = {0}, available = {1}", totalBytes, availableBytes)); int totalCloudFiles = MyGameService.GetRemoteStorageFileCount(); MySandboxGame.Log.WriteLineAndConsole(string.Format("Listing cloud {0} files", totalCloudFiles)); MySandboxGame.Log.IncreaseIndent(); for (int i = 0; i < totalCloudFiles; ++i) { int fileSize = 0; string fileName = MyGameService.GetRemoteStorageFileNameAndSize(i, out fileSize); bool persisted = MyGameService.IsRemoteStorageFilePersisted(fileName); bool forgot = false; // Here's how the if works: // Delete if --force AND no files were manually specified // OR if the file specified matches the file on the cloud if ((force && filesToDelete == null) || (persisted && fileName.StartsWith("tmp") && fileName.EndsWith(".tmp")) || (filesToDelete?.Length > 0 && filesToDelete.Contains(fileName, StringComparer.CurrentCultureIgnoreCase))) // dont sync useless temp files { forgot = MyGameService.RemoteStorageFileForget(fileName); // force actually deletes the file on local disk, don't do that unless --force specified if (force) { forgot = MyGameService.DeleteFromCloud(fileName); // Delete is immediate, and alters the count, so adjust for that totalCloudFiles--; i--; } } MySandboxGame.Log.WriteLineAndConsole(string.Format("'{0}', {1}B, {2}, {3}", fileName, fileSize, persisted, forgot)); } MySandboxGame.Log.DecreaseIndent(); MyGameService.GetRemoteStorageQuota(out totalBytes, out availableBytes); MySandboxGame.Log.WriteLineAndConsole(string.Format("Quota: total = {0}, available = {1}", totalBytes, availableBytes)); #endif return(true); }); return(Task); }
void PrintItemDetails() { const int MAX_LENGTH = 40; MySandboxGame.Log.WriteLineAndConsole(string.Format("Visibility: {0}", m_visibility)); MySandboxGame.Log.WriteLineAndConsole(string.Format("Tags: {0}", string.Join(", ", m_tags))); if (!string.IsNullOrEmpty(m_description)) { MySandboxGame.Log.WriteLineAndConsole($"Description: {m_description.Substring(0, Math.Min(m_description.Length, MAX_LENGTH))}{(m_description.Length > MAX_LENGTH ? "..." : "")}"); } if (!string.IsNullOrEmpty(m_changelog)) { MySandboxGame.Log.WriteLineAndConsole($"Changelog: {m_changelog.Substring(0, Math.Min(m_changelog.Length, MAX_LENGTH))}{(m_changelog.Length > MAX_LENGTH ? "..." : "")}"); } #if SE MySandboxGame.Log.WriteLineAndConsole(string.Format("DLC requirements: {0}", (m_dlcs?.Length > 0 ? string.Join(", ", m_dlcs.Select(i => { try { return(Sandbox.Game.MyDLCs.DLCs[i].Name); } catch { return($"Unknown({i})"); } })) : "None"))); #endif MySandboxGame.Log.WriteLineAndConsole(string.Format("Dependencies: {0}", (m_deps?.Length > 0 ? string.Empty : "None"))); if (m_deps?.Length > 0) { var depItems = new List <MyWorkshopItem>(); var width = Console.IsOutputRedirected ? 256 : Console.WindowWidth; #if SE var depIds = new List <WorkshopId>(); foreach (var item in m_deps) { depIds.Add(new WorkshopId(item, MyGameService.GetDefaultUGC().ServiceName)); } if (MyWorkshop.GetItemsBlockingUGC(depIds, depItems)) #else if (MyWorkshop.GetItemsBlocking(m_deps, depItems)) #endif { depItems.ForEach(i => MySandboxGame.Log.WriteLineAndConsole(string.Format("{0,15} -> {1}", i.Id, i.Title.Substring(0, Math.Min(i.Title.Length, width - 45))))); } else { MySandboxGame.Log.WriteLineAndConsole(string.Format(" {0}", string.Join(", ", m_deps))); } } MySandboxGame.Log.WriteLineAndConsole(string.Format("Thumbnail: {0}", m_previewFilename ?? "No change")); ValidateThumbnail(); }
public void PingServerAndBeginRedirect() { if (TargetServerID == 0) { SeamlessClient.TryShow("This is not a valid server!"); return; } SeamlessClient.TryShow("SyncMyID: " + Sync.MyId.ToString()); SeamlessClient.TryShow("Beginning Redirect to server: " + TargetServerID); MyGameService.OnPingServerResponded += MyGameService_OnPingServerResponded; MyGameService.OnPingServerFailedToRespond += MyGameService_OnPingServerFailedToRespond; MyGameService.PingServer(IPAdress); }
public static string Connect(List <string> args) { if (args.Count < 1) { return("Not enough arguments!"); } try { string[] array = args[0].Trim().Split(new char[] { ':' }); ushort num; if (array.Length < 2) { num = 27016; } else { num = ushort.Parse(array[1]); } IPAddress[] hostAddresses = Dns.GetHostAddresses(array[0]); StringBuilder text = MyTexts.Get(MyCommonTexts.DialogTextJoiningWorld); m_progressScreen = new MyGuiScreenProgress(text, new MyStringId?(MyCommonTexts.Cancel), false, true); MyGuiSandbox.AddScreen(m_progressScreen); m_progressScreen.ProgressCancelled += delegate { CloseHandlers(); MySessionLoader.UnloadAndExitToMenu(); }; MyGameService.OnPingServerResponded += new EventHandler <MyGameServerItem>(ServerResponded); MyGameService.OnPingServerFailedToRespond += new EventHandler(ServerFailedToRespond); MyGameService.PingServer(hostAddresses[0].ToIPv4NetworkOrder(), num); MyGameService.OnPingServerResponded += new EventHandler <MyGameServerItem>(ServerResponded); MyGameService.OnPingServerFailedToRespond += new EventHandler(ServerFailedToRespond); MyGameService.PingServer(hostAddresses[0].ToIPv4NetworkOrder(), num); } catch (Exception ex) { MyGuiSandbox.Show(MyTexts.Get(MyCommonTexts.MultiplayerJoinIPError), MyCommonTexts.MessageBoxCaptionError, MyMessageBoxStyleEnum.Error); } return("Attempting to join server: "); }
private string GetThumbnail(MyObjectBuilder_LastSession session) { string text = session?.Path; if (text == null) { return(null); } if (Directory.Exists(text + MyGuiScreenLoadSandbox.CONST_BACKUP)) { string[] directories = Directory.GetDirectories(text + MyGuiScreenLoadSandbox.CONST_BACKUP); if (Enumerable.Any(directories)) { string text2 = Path.Combine(Enumerable.Last(directories), MyTextConstants.SESSION_THUMB_NAME_AND_EXTENSION); if (File.Exists(text2) && new FileInfo(text2).Length > 0) { return(text2); } } } string text3 = Path.Combine(text, MyTextConstants.SESSION_THUMB_NAME_AND_EXTENSION); if (File.Exists(text3) && new FileInfo(text3).Length > 0) { return(text3); } if (MyPlatformGameSettings.GAME_SAVES_TO_CLOUD) { byte[] array = MyGameService.LoadFromCloud(MyCloudHelper.Combine(MyCloudHelper.LocalToCloudWorldPath(text + "/"), MyTextConstants.SESSION_THUMB_NAME_AND_EXTENSION)); if (array != null) { try { string text4 = Path.Combine(text, MyTextConstants.SESSION_THUMB_NAME_AND_EXTENSION); Directory.CreateDirectory(text); File.WriteAllBytes(text4, array); MyRenderProxy.UnloadTexture(text4); return(text4); } catch { } } } return(null); }
public static ResultData DownloadWorldModsBlocking(List <MyObjectBuilder_Checkpoint.ModItem> mods, CancelToken cancelToken) { ResultData ret = default; Task task = Parallel.Start(() => { ret = DownloadWorldModsBlockingInternal(mods, cancelToken); }); while (!task.IsComplete) { MyGameService.Update(); Thread.Sleep(10); } return(ret); }
private void GameServer_ValidateAuthTicketResponse(ulong steamID, JoinResult response, ulong steamOwner) { object[] objArray1 = new object[] { "Server ValidateAuthTicketResponse (", response, "), owner: ", steamOwner }; MyLog.Default.WriteLineAndConsole(string.Concat(objArray1)); if (base.IsClientBanned(steamOwner) || MySandboxGame.ConfigDedicated.Banned.Contains(steamOwner)) { this.UserRejected(steamID, JoinResult.BannedByAdmins); base.RaiseClientKicked(steamID); } else if (base.IsClientKicked(steamOwner)) { this.UserRejected(steamID, JoinResult.KickedRecently); base.RaiseClientKicked(steamID); } else if (response != JoinResult.OK) { this.UserRejected(steamID, response); } else if ((MySandboxGame.ConfigDedicated.Administrators.Contains(steamID.ToString()) || MySandboxGame.ConfigDedicated.Administrators.Contains(ConvertSteamIDFrom64(steamID))) || MySandboxGame.ConfigDedicated.Reserved.Contains(steamID)) { this.UserAccepted(steamID); } else if ((this.MemberLimit > 0) && ((this.m_members.Count - 1) >= this.MemberLimit)) { this.UserRejected(steamID, JoinResult.ServerFull); } else if (this.m_groupId == 0) { this.UserAccepted(steamID); } else if (MyGameService.GetServerAccountType(this.m_groupId) != MyGameServiceAccountType.Clan) { this.UserRejected(steamID, JoinResult.GroupIdInvalid); } else if (MyGameService.GameServer.RequestGroupStatus(steamID, this.m_groupId)) { this.m_waitingForGroup.Add(steamID); } else { this.UserRejected(steamID, JoinResult.SteamServersOffline); } }
public static void Update(IEnumerable <ulong> ids) { if (!ids.Any()) { return; } var modItems = new List <MyObjectBuilder_Checkpoint.ModItem>(ids.Select(x => new MyObjectBuilder_Checkpoint.ModItem(x, "Steam"))); LogFile.WriteLine($"Updating {modItems.Count} workshop items"); // Source: MyWorkshop.DownloadWorldModsBlocking MyWorkshop.ResultData result = new MyWorkshop.ResultData(); Task task = Parallel.Start(delegate { result = UpdateInternal(modItems); }); while (!task.IsComplete) { MyGameService.Update(); Thread.Sleep(10); } if (!result.Success) { Exception[] exceptions = task.Exceptions; if (exceptions != null && exceptions.Length > 0) { StringBuilder sb = new StringBuilder(); sb.AppendLine("An error occurred while updating workshop items:"); foreach (Exception e in exceptions) { sb.Append(e); } LogFile.WriteLine(sb.ToString()); } else { LogFile.WriteLine("Unable to update workshop items"); } } }
private void Matchmaking_LobbyChatUpdate(IMyLobby lobby, ulong changedUser, ulong makingChangeUser, MyChatMemberStateChangeEnum stateChange) { if (lobby.LobbyId == this.Lobby.LobbyId) { if (stateChange != MyChatMemberStateChangeEnum.Entered) { if ((Sync.Clients == null) || Sync.Clients.HasClient(changedUser)) { base.RaiseClientLeft(changedUser, stateChange); } if (changedUser == base.ServerId) { base.RaiseHostLeft(); MySessionLoader.UnloadAndExitToMenu(); MyGuiScreenServerReconnector.ReconnectToLastSession(); } else if (MySandboxGame.IsGameReady) { MyHudNotification notification = new MyHudNotification(MyCommonTexts.NotificationClientDisconnected, 0x1388, "Blue", MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, 0, MyNotificationLevel.Important); object[] arguments = new object[] { MyGameService.GetPersonaName(changedUser) }; notification.SetTextFormatArguments(arguments); MyHud.Notifications.Add(notification); } } else { object[] objArray1 = new object[] { "Player entered: ", MyGameService.GetPersonaName(changedUser), " (", changedUser, ")" }; MySandboxGame.Log.WriteLineAndConsole(string.Concat(objArray1)); MyGameService.Peer2Peer.AcceptSession(changedUser); if ((Sync.Clients == null) || !Sync.Clients.HasClient(changedUser)) { base.RaiseClientJoined(changedUser); } if (MySandboxGame.IsGameReady && (changedUser != base.ServerId)) { MyHudNotification notification = new MyHudNotification(MyCommonTexts.NotificationClientConnected, 0x1388, "Blue", MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, 0, MyNotificationLevel.Important); object[] arguments = new object[] { MyGameService.GetPersonaName(changedUser) }; notification.SetTextFormatArguments(arguments); MyHud.Notifications.Add(notification); } } } }
public static void StartServerPing(Transfer ClientTransfer) { // We need to first ping the server to make sure its running and so we can get a connection Transfer = ClientTransfer; Request = Transfer.WorldRequest; if (Transfer.TargetServerID == 0) { SeamlessClient.TryShow("This is not a valid server!"); return; } SeamlessClient.TryShow("Beginning Redirect to server: " + Transfer.TargetServerID); MyGameService.OnPingServerResponded += PingResponded; MyGameService.OnPingServerFailedToRespond += FailedToRespond; MyGameService.PingServer(Transfer.IPAdress); }
public override void Dispose() { MyGameService.ShutDown(); _startup.DetectSharpDxLeaksAfterRun(); MyInitializer.InvokeAfterRun(); }
public static WorkshopId ToWorkshopId(this ulong id) { return(new VRage.Game.WorkshopId(id, MyGameService.GetDefaultUGC().ServiceName)); }
static bool ProcessItemsDownload(WorkshopType type, string[] paths, Options options) { if (paths == null) { return(true); } var width = Console.IsOutputRedirected ? 256 : Console.WindowWidth; var items = new List <MyWorkshopItem>(); var modids = paths.Select(ulong.Parse); MySandboxGame.Log.WriteLineAndConsole(string.Format("Processing {0}s...", type.ToString())); var downloadPath = WorkshopHelper.GetWorkshopItemPath(type); #if SE var workshopIds = new List <VRage.Game.WorkshopId>(); foreach (var id in modids) { workshopIds.Add(new VRage.Game.WorkshopId(id, MyGameService.GetDefaultUGC().ServiceName)); } if (MyWorkshop.GetItemsBlockingUGC(workshopIds, items)) #else if (MyWorkshop.GetItemsBlocking(modids, items)) #endif { System.Threading.Thread.Sleep(1000); // Fix for DLC not being filled in bool success = false; if (type == WorkshopType.Mod) { #if SE var result = MyWorkshop.DownloadModsBlockingUGC(items, null); #else var result = MyWorkshop.DownloadModsBlocking(items, null); #endif success = result.Success; } else { if (type == WorkshopType.Blueprint) { var loopsuccess = false; foreach (var item in items) { #if SE loopsuccess = MyWorkshop.DownloadBlueprintBlockingUGC(item); #else loopsuccess = MyWorkshop.DownloadBlueprintBlocking(item, null); #endif if (!loopsuccess) { MySandboxGame.Log.WriteLineAndConsole(string.Format("Download of {0} FAILED!", item.Id)); } else { success = true; } } } #if SE else if (type == WorkshopType.IngameScript) { var loopsuccess = false; foreach (var item in items) { loopsuccess = MyWorkshop.DownloadScriptBlocking(item); if (!loopsuccess) { MySandboxGame.Log.WriteLineAndConsole(string.Format("Download of {0} FAILED!", item.Id)); } else { success = true; } } } #endif #if SE else if (type == WorkshopType.World || type == WorkshopType.Scenario) { var loopsuccess = false; string path; MyWorkshop.MyWorkshopPathInfo pathinfo = type == WorkshopType.World ? MyWorkshop.MyWorkshopPathInfo.CreateWorldInfo() : MyWorkshop.MyWorkshopPathInfo.CreateScenarioInfo(); foreach (var item in items) { // This downloads and extracts automatically, no control over it loopsuccess = MyWorkshop.TryCreateWorldInstanceBlocking(item, pathinfo, out path, false); if (!loopsuccess) { MySandboxGame.Log.WriteLineAndConsole(string.Format("Download of {0} FAILED!", item.Id)); } else { MySandboxGame.Log.WriteLineAndConsole(string.Format("Downloaded '{0}' to {1}", item.Title, path)); success = true; } } } #endif else { throw new NotSupportedException(string.Format("Downloading of {0} not yet supported.", type.ToString())); } } if (success) { MySandboxGame.Log.WriteLineAndConsole("Download success!"); } else { MySandboxGame.Log.WriteLineAndConsole("Download FAILED!"); return(false); } foreach (var item in items) { MySandboxGame.Log.WriteLineAndConsole(string.Format("Downloading mod: {0}; {1}", item.Id, item.Title)); MySandboxGame.Log.WriteLineAndConsole(string.Format("Visibility: {0}", item.Visibility)); MySandboxGame.Log.WriteLineAndConsole(string.Format("Tags: {0}", string.Join(", ", string.Join(", ", item.Tags)))); #if SE MySandboxGame.Log.WriteLineAndConsole(string.Format("DLC requirements: {0}", (item.DLCs.Count > 0 ? string.Join(", ", item.DLCs.Select(i => { try { return(Sandbox.Game.MyDLCs.DLCs[i].Name); } catch { return($"Unknown({i})"); } })) : "None"))); #endif MySandboxGame.Log.WriteLineAndConsole(string.Format("Dependencies: {0}", (item.Dependencies.Count > 0 ? string.Empty : "None"))); if (item.Dependencies.Count > 0) { List <MyWorkshopItem> depItems = new List <MyWorkshopItem>(); #if SE workshopIds.Clear(); foreach (var id in item.Dependencies) { workshopIds.Add(new VRage.Game.WorkshopId(id, MyGameService.GetDefaultUGC().ServiceName)); } if (MyWorkshop.GetItemsBlockingUGC(workshopIds, depItems)) #else if (MyWorkshop.GetItemsBlocking(item.Dependencies, depItems)) #endif { depItems.ForEach(i => MySandboxGame.Log.WriteLineAndConsole(string.Format("{0,15} -> {1}", i.Id, i.Title.Substring(0, Math.Min(i.Title.Length, width - 45))))); } else { MySandboxGame.Log.WriteLineAndConsole(string.Format(" {0}", string.Join(", ", item.Dependencies))); } } MySandboxGame.Log.WriteLineAndConsole(string.Format("Location: {0}", item.Folder)); if (options.Extract) { var mod = new Downloader(downloadPath, item); mod.Extract(); } MySandboxGame.Log.WriteLineAndConsole(string.Empty); } } return(true); }
/// <summary> /// Publishes the mod to the workshop /// </summary> /// <returns></returns> public bool Publish() { bool newMod = false; if (!Directory.Exists(m_modPath)) { MySandboxGame.Log.WriteLineAndConsole(string.Format("Directory does not exist {0}. Wrong option?", m_modPath ?? string.Empty)); return(false); } // Upload/Publish #if SE if (((IMod)this).ModId == 0) #else if (m_modId == 0) #endif { MySandboxGame.Log.WriteLineAndConsole(string.Format("Uploading new {0}: {1}", m_type.ToString(), m_title)); newMod = true; #if SE if (m_modId.Length == 0) { m_modId = new WorkshopId[1] { new WorkshopId(0, MyGameService.GetDefaultUGC().ServiceName) } } ; #endif } else { MySandboxGame.Log.WriteLineAndConsole(string.Format("Updating {0}: {1}; {2}", m_type.ToString(), m_modId.AsString(), m_title)); } // Add the global game filter for file extensions _globalIgnoredExtensions?.ForEach(s => m_ignoredExtensions.Add(s)); // Process Tags ProcessTags(); PrintItemDetails(); MyWorkshopItem[] items = null; if (m_dryrun) { MySandboxGame.Log.WriteLineAndConsole("DRY-RUN; Publish skipped"); return(true); } else { if (_publishMethod != null) { InjectedMethod.ChangeLog = m_changelog; #if SE var result = _publishMethod(m_modPath, m_title, m_description, m_modId, (MyPublishedFileVisibility)(m_visibility ?? PublishedFileVisibility.Private), m_tags, m_ignoredExtensions, m_ignoredPaths, m_dlcs, out items); PublishSuccess = result.Item1 == MyGameServiceCallResult.OK; if (PublishSuccess) { m_modId = items.Select(i => new WorkshopId(i.Id, i.ServiceName)).ToArray(); } #else m_modId = _publishMethod(m_modPath, m_title, m_description, m_modId, (MyPublishedFileVisibility)(m_visibility ?? PublishedFileVisibility.Private), m_tags, m_ignoredExtensions, m_ignoredPaths); #endif } else { MySandboxGame.Log.WriteLineAndConsole(string.Format(Constants.ERROR_Reflection, "PublishItemBlocking")); } // SE libraries don't support updating dependencies, so we have to do that separately WorkshopHelper.PublishDependencies(m_modId, m_deps, m_depsToRemove); } if (((IMod)this).ModId == 0 || !PublishSuccess) { MySandboxGame.Log.WriteLineAndConsole("Upload/Publish FAILED!"); return(false); } else { MySandboxGame.Log.WriteLineAndConsole(string.Format("Upload/Publish success: {0}", m_modId.AsString())); if (newMod) { #if SE if (MyWorkshop.GenerateModInfo(m_modPath, items, MyGameService.UserId)) #else if (MyWorkshop.UpdateModMetadata(m_modPath, m_modId, MySteam.UserId)) #endif { MySandboxGame.Log.WriteLineAndConsole(string.Format("Create modinfo.sbmi success: {0}", m_modId.AsString())); } else { MySandboxGame.Log.WriteLineAndConsole(string.Format("Create modinfo.sbmi FAILED: {0}", m_modId.AsString())); return(false); } } } return(true); } bool FillPropertiesFromPublished() { var results = new List <MyWorkshopItem>(); #if SE if (MyWorkshop.GetItemsBlockingUGC(m_modId.ToList(), results)) #else if (MyWorkshop.GetItemsBlocking(new List <ulong>() { m_modId }, results)) #endif { System.Threading.Thread.Sleep(1000); // Fix for DLC not being filled in if (results.Count > 0) { #if SE m_workshopItems[m_modId[0]] = results[0]; if (m_modId.Length > 1 && results.Count > 1) { m_workshopItems[m_modId[1]] = results[1]; } #else if (results.Count > 1) { m_modId = results[0].Id; } #endif m_title = results[0].Title; // Check if the mod owner in the sbmi matches steam owner var owner = results[0].OwnerId; if (m_visibility == null) { m_visibility = (PublishedFileVisibility)(int)results[0].Visibility; } #if SE m_dlcs = results[0].DLCs.ToArray(); #endif m_deps = results[0].Dependencies.ToArray(); MyDebug.AssertDebug(owner == MyGameService.UserId); if (owner != MyGameService.UserId) { MySandboxGame.Log.WriteLineAndConsole(string.Format("Owner mismatch! Mod owner: {0}; Current user: {1}", owner, MyGameService.UserId)); MySandboxGame.Log.WriteLineAndConsole("Upload/Publish FAILED!"); return(false); } return(true); } return(false); } return(true); } void ProcessTags() { // TODO: This code could be better. // Get the list of existing tags, if there are any var existingTags = GetTags(); var length = m_tags.Length; // Order or tag processing matters // 1) Copy mod type into tags var modtype = m_type.ToString(); // 2) Verify the modtype matches what was listed in the workshop // TODO If type doesn't match, process as workshop type if (existingTags != null && existingTags.Length > 0) { MyDebug.AssertRelease(existingTags.Contains(modtype, StringComparer.InvariantCultureIgnoreCase), string.Format("Mod type '{0}' does not match workshop '{1}'", modtype, existingTags[0])); } #if SE // 3a) check if user passed in the 'development' tag // If so, remove it, and mark the mod as 'dev' so it doesn't get flagged later if (m_tags.Contains(MyWorkshop.WORKSHOP_DEVELOPMENT_TAG)) { m_tags = (from tag in m_tags where tag != MyWorkshop.WORKSHOP_DEVELOPMENT_TAG select tag).ToArray(); m_isDev = true; } #endif // 3b If tags contain mod type, remove it if (m_tags.Contains(modtype, StringComparer.InvariantCultureIgnoreCase)) { m_tags = (from tag in m_tags where string.Compare(tag, modtype, true) != 0 select tag).ToArray(); } // 4) if (m_tags.Length == 1 && m_tags[0] == null && existingTags != null && existingTags.Length > 0) { // 4a) If user passed no tags, use existing ones Array.Resize(ref m_tags, existingTags.Length); Array.Copy(existingTags, m_tags, existingTags.Length); } else { // 4b) Verify passed in tags are valid for this mod type var validTags = new List <MyWorkshop.Category>() { #if SE // 'obsolete' tag is always available, as is 'No Mods' and 'experimental' new MyWorkshop.Category() { Id = "obsolete" }, new MyWorkshop.Category() { Id = "no mods" }, new MyWorkshop.Category() { Id = "experimental" }, #endif }; switch (m_type) { case WorkshopType.Mod: MyWorkshop.ModCategories.ForEach(c => validTags.Add(c)); // Mods have extra tags not in this list #if SE validTags.Add(new MyWorkshop.Category() { Id = "campaign" }); validTags.Add(new MyWorkshop.Category() { Id = "font" }); validTags.Add(new MyWorkshop.Category() { Id = "noscripts" }); #endif break; case WorkshopType.Blueprint: MyWorkshop.BlueprintCategories.ForEach(c => validTags.Add(c)); #if SE // Blueprints have extra tags not in this list validTags.Add(new MyWorkshop.Category() { Id = "large_grid" }); validTags.Add(new MyWorkshop.Category() { Id = "small_grid" }); validTags.Add(new MyWorkshop.Category() { Id = "safe" }); // Mod.io only? #endif break; case WorkshopType.Scenario: MyWorkshop.ScenarioCategories.ForEach(c => validTags.Add(c)); break; case WorkshopType.World: MyWorkshop.WorldCategories.ForEach(c => validTags.Add(c)); break; case WorkshopType.IngameScript: //tags = new MyWorkshop.Category[0]; // There are none currently break; default: MyDebug.FailRelease("Invalid category."); break; } // This query gets all the items in 'm_tags' that do *not* exist in 'validTags' // This is for detecting invalid tags passed in var invalidItems = from utag in m_tags where !( from tag in validTags select tag.Id ).Contains(utag, StringComparer.InvariantCultureIgnoreCase) select utag; if (invalidItems.Count() > 0) { MySandboxGame.Log.WriteLineAndConsole(string.Format("{0} invalid tags: {1}", (m_force ? "Forced" : "Removing"), string.Join(", ", invalidItems))); if (!m_force) { m_tags = (from tag in m_tags where !invalidItems.Contains(tag) select tag).ToArray(); } } // Now prepend the 'Type' tag string[] newTags = new string[m_tags.Length + 1]; newTags[0] = m_type.ToString(); var tags = from tag in validTags select tag.Id; // Convert all tags to proper-case for (var x = 0; x < m_tags.Length; x++) { var tag = m_tags[x]; var newtag = (from vtag in tags where (string.Compare(vtag, tag, true) == 0) select vtag).FirstOrDefault(); if (!string.IsNullOrEmpty(newtag)) { newTags[x + 1] = newtag; } else { newTags[x + 1] = m_tags[x]; } } m_tags = newTags; } #if SE // 5) Set or clear development tag if (m_isDev) { // If user selected dev, add dev tag if (!m_tags.Contains(MyWorkshop.WORKSHOP_DEVELOPMENT_TAG)) { Array.Resize(ref m_tags, m_tags.Length + 1); m_tags[m_tags.Length - 1] = MyWorkshop.WORKSHOP_DEVELOPMENT_TAG; } } else { // If not, remove tag if (m_tags.Contains(MyWorkshop.WORKSHOP_DEVELOPMENT_TAG)) { m_tags = (from tag in m_tags where tag != MyWorkshop.WORKSHOP_DEVELOPMENT_TAG select tag).ToArray(); } } #endif // 6) Strip empty values m_tags = m_tags.Where(x => !string.IsNullOrEmpty(x)).ToArray(); // Done } string[] GetTags() { var results = new List <MyWorkshopItem>(); #if SE if (MyWorkshop.GetItemsBlockingUGC(m_modId.ToList(), results)) #else if (MyWorkshop.GetItemsBlocking(new List <ulong>() { m_modId }, results)) #endif { if (results.Count > 0) { return(results[0].Tags.ToArray()); } else { return(null); } } return(null); } uint[] GetDLC() { #if SE var results = new List <MyWorkshopItem>(); if (MyWorkshop.GetItemsBlockingUGC(m_modId.ToList(), results)) { if (results.Count > 0) { return(results[0].DLCs.ToArray()); } else { return(null); } } #endif return(null); } PublishedFileVisibility GetVisibility() { var results = new List <MyWorkshopItem>(); #if SE if (MyWorkshop.GetItemsBlockingUGC(m_modId.ToList(), results)) #else if (MyWorkshop.GetItemsBlocking(new List <ulong>() { m_modId }, results)) #endif { if (results.Count > 0) { return((PublishedFileVisibility)(int)results[0].Visibility); } else { return(PublishedFileVisibility.Private); } } return(PublishedFileVisibility.Private); }
public override string GetMemberName(ulong steamUserID) => MyGameService.GetPersonaName(steamUserID);
public Uploader(WorkshopType type, string path, string[] tags = null, string[] ignoredExtensions = null, string[] ignoredPaths = null, bool compile = false, bool dryrun = false, bool development = false, PublishedFileVisibility?visibility = null, bool force = false, string previewFilename = null, string[] dlcs = null, ulong[] deps = null, string description = null, string changelog = null) { m_modPath = path; if (ulong.TryParse(m_modPath, out ulong id)) #if SE { m_modId = new[] { new WorkshopId(id, MyGameService.GetDefaultUGC().ServiceName) } }; #else { m_modId = id; } #endif else #if SE { m_modId = MyWorkshop.GetWorkshopIdFromMod(m_modPath); } #else { m_modId = MyWorkshop.GetWorkshopIdFromLocalMod(m_modPath) ?? 0; } #endif // Fill defaults before assigning user-defined ones FillPropertiesFromPublished(); m_compile = compile; m_dryrun = dryrun; if (visibility != null) { m_visibility = visibility; } if (string.IsNullOrEmpty(m_title)) { m_title = Path.GetFileName(path); } m_description = description; m_changelog = changelog; m_type = type; m_isDev = development; m_force = force; if (previewFilename != null) { m_previewFilename = previewFilename; } #if SE var mappedlc = MapDLCStringsToInts(dlcs); // If user specified "0" or "none" for DLCs, remove all of them if (dlcs != null) { m_dlcs = mappedlc; } #endif if (tags != null) { m_tags = tags; } if (deps != null) { // Any dependencies that existed, but weren't specified, will be removed if (m_deps != null) { m_depsToRemove = m_deps.Except(deps).ToArray(); } m_deps = deps; } // This file list should match the PublishXXXAsync methods in MyWorkshop switch (m_type) { case WorkshopType.Mod: m_ignoredPaths.Add("modinfo.sbmi"); break; case WorkshopType.IngameScript: break; case WorkshopType.World: m_ignoredPaths.Add("Backup"); break; case WorkshopType.Blueprint: break; case WorkshopType.Scenario: break; } if (ignoredExtensions != null) { ignoredExtensions = ignoredExtensions.Select(s => "." + s.TrimStart(new[] { '.', '*' })).ToArray(); ignoredExtensions.ForEach(s => m_ignoredExtensions.Add(s)); } if (ignoredPaths != null) { ignoredPaths.ForEach(s => m_ignoredPaths.Add(s)); } // Start with the parent file, if it exists. This is at %AppData%\SpaceEngineers\Mods. if (IgnoreFile.TryLoadIgnoreFile(Path.Combine(m_modPath, "..", ".wtignore"), Path.GetFileName(m_modPath), out var extensionsToIgnore, out var pathsToIgnore)) { extensionsToIgnore.ForEach(s => m_ignoredExtensions.Add(s)); pathsToIgnore.ForEach(s => m_ignoredPaths.Add(s)); } if (IgnoreFile.TryLoadIgnoreFile(Path.Combine(m_modPath, ".wtignore"), out extensionsToIgnore, out pathsToIgnore)) { extensionsToIgnore.ForEach(s => m_ignoredExtensions.Add(s)); pathsToIgnore.ForEach(s => m_ignoredPaths.Add(s)); } SetupReflection(); }
/// <summary> /// Compiles the mod /// </summary> /// <returns></returns> public bool Compile() { // Compile if (m_compile) { if (m_type == WorkshopType.Mod) { if (_compileMethod != null) { MySandboxGame.Log.WriteLineAndConsole("Compiling..."); #if SE var mod = new MyModContext(); // Because of a regression in SE, we need to create a checkpoint ModItem to set the Id. var modob = new MyObjectBuilder_Checkpoint.ModItem(); modob.Name = Path.GetFileName(m_modPath); if (ModId.Length > 0) { modob.PublishedFileId = m_workshopItems[m_modId[0]].Id; modob.PublishedServiceName = m_workshopItems[m_modId[0]].ServiceName; modob.FriendlyName = m_workshopItems[m_modId[0]].Title; modob.SetModData(m_workshopItems[m_modId[0]]); } else { // Fake it, so the compile still works modob.PublishedFileId = 0; modob.PublishedServiceName = MyGameService.GetDefaultUGC().ServiceName; modob.FriendlyName = Title; } mod.Init(modob); // Call init again, to make sure the path in set properly to the local mod directory mod.Init(m_title, null, m_modPath); #else var workshopItem = new MyLocalWorkshopItem(new VRage.ObjectBuilders.SerializableModReference(Path.GetFileName(m_modPath), 0)); var mod = new MyModContext(workshopItem, 0); #endif _compileMethod( #if SE m_modPath, #endif mod ); // Process any errors #if SE var errors = MyDefinitionErrors.GetErrors(); #else var compileMessages = _scriptManager.GetType().GetField("m_messages", BindingFlags.NonPublic | BindingFlags.Instance); var errors = (compileMessages.GetValue(_scriptManager) as List <MyScriptCompiler.Message>) ?? new List <MyScriptCompiler.Message>(); #endif if (errors.Count > 0) { int errorCount = 0; int warningCount = 0; // This is not efficient, but I'm lazy foreach (var error in errors) { if (error.Severity >= TErrorSeverity.Error) { errorCount++; } if (error.Severity == TErrorSeverity.Warning) { warningCount++; } } if (errorCount > 0) { MySandboxGame.Log.WriteLineAndConsole(string.Format("There are {0} compile errors:", errorCount)); } if (warningCount > 0) { MySandboxGame.Log.WriteLineAndConsole(string.Format("There are {0} compile warnings:", warningCount)); } // Output raw message, which is usually in msbuild friendly format, for automated tools foreach (var error in errors) #if SE { System.Console.WriteLine(error.Message); } #else { System.Console.WriteLine(error.Text); } #endif #if SE MyDefinitionErrors.Clear(); // Clear old ones, so next mod starts fresh #endif if (errorCount > 0) { MySandboxGame.Log.WriteLineAndConsole("Compilation FAILED!"); return(false); } } MySandboxGame.Log.WriteLineAndConsole("Compilation successful!"); } else { MySandboxGame.Log.WriteLineAndConsole(string.Format(Constants.ERROR_Reflection, "LoadScripts")); } } #if SE else if (m_type == WorkshopType.IngameScript) { // Load the ingame script from the disk // I don't like this, but meh var input = new StreamReader(Path.Combine(m_modPath, "Script.cs")); var program = input.ReadToEnd(); input.Close(); var scripts = new List <Script>(); scripts.Add(MyScriptCompiler.Static.GetIngameScript(program, "Program", typeof(Sandbox.ModAPI.Ingame.MyGridProgram).Name, "sealed partial")); var messages = new List <Message>(); var assembly = MyVRage.Platform.Scripting.CompileIngameScriptAsync(Path.Combine(VRage.FileSystem.MyFileSystem.UserDataPath, "SEWT-Script" + Path.GetFileName(m_modPath)), program, out messages, "SEWT Compiled PB Script", "Program", typeof(Sandbox.ModAPI.Ingame.MyGridProgram).Name).Result; if (messages.Count > 0) { MySandboxGame.Log.WriteLineAndConsole(string.Format("There are {0} compile messages:", messages.Count)); int errors = 0; foreach (var msg in messages) { MySandboxGame.Log.WriteLineAndConsole(msg.Text); if (msg.IsError) { errors++; } } if (errors > 0) { return(false); } } if (assembly == null) { return(false); } } #endif return(true); } return(true); }
public static WorkshopId[] ToWorkshopIds(this IEnumerable <ulong> ids) { return(ids.Select(id => new VRage.Game.WorkshopId(id, MyGameService.GetDefaultUGC().ServiceName)).ToArray()); }
public bool UpdatePreviewFileOrTags() { return(UpdatePreviewFileOrTags(ModId, MyGameService.CreateWorkshopPublisher())); }
static bool ProcessItemsUpload(WorkshopType type, List <string> paths, Options options) { bool success = true; for (int idx = 0; idx < paths.Count; idx++) { var pathname = Path.GetFullPath(paths[idx]); // Check if path is really a modid (this is kind of hacky right now) if (!Directory.Exists(pathname) && ulong.TryParse(paths[idx], out var id)) { if (options.Compile) { MySandboxGame.Log.WriteLineAndConsole(string.Format("'--compile' option not valid with a ModID: {0}", id)); continue; } pathname = paths[idx]; } var tags = options.Tags; // If user comma-separated the tags, split them if (tags != null && tags.Length == 1) { tags = tags[0].Split(',', ';'); } if (!string.IsNullOrEmpty(options.Thumbnail) && !Path.IsPathRooted(options.Thumbnail)) { options.Thumbnail = Path.GetFullPath(Path.Combine(LaunchDirectory, options.Thumbnail)); } // Read the description filename, if set string description = null; if (!string.IsNullOrEmpty(options.DescriptionFile)) { if (!Path.IsPathRooted(options.DescriptionFile)) { options.DescriptionFile = Path.GetFullPath(Path.Combine(LaunchDirectory, options.DescriptionFile)); } if (File.Exists(options.DescriptionFile)) { description = File.ReadAllText(options.DescriptionFile); } else { MySandboxGame.Log.WriteLineAndConsole(string.Format("Unable to set description, file does not exist: {0}", options.DescriptionFile)); } } // Read the changelog from a file, if detected var changelog = options.Changelog; if (!string.IsNullOrEmpty(options.Changelog)) { try { if (!Path.IsPathRooted(options.Changelog)) { var rootedPath = Path.GetFullPath(Path.Combine(LaunchDirectory, options.Changelog)); if (File.Exists(rootedPath)) { options.Changelog = rootedPath; } } if (File.Exists(options.Changelog)) { MySandboxGame.Log.WriteLineAndConsole(string.Format("Reading changelog from file: {0}", options.Changelog)); changelog = File.ReadAllText(options.Changelog); } } catch (Exception ex) when(ex is NotSupportedException || ex is IOException || ex is ArgumentException) { // Assume the string provided isn't a filename // Could contain invalid characters that GetFullPath can't handle. } } var mod = new Uploader(type, pathname, tags, options.ExcludeExtensions, options.IgnorePaths, options.Compile, options.DryRun, options.Development, options.Visibility, options.Force, options.Thumbnail, options.DLCs, options.Dependencies, description, options.Changelog); if (options.UpdateOnly && ((IMod)mod).ModId == 0) { MySandboxGame.Log.WriteLineAndConsole(string.Format("--update-only passed, skipping: {0}", mod.Title)); continue; } MySandboxGame.Log.WriteLineAndConsole(string.Format("Processing {0}: {1}", type.ToString(), mod.Title)); if (mod.Compile()) { if (!SteamAPI.IsSteamRunning()) { MySandboxGame.Log.WriteLineAndConsole("Cannot publish, Steam not detected!"); return(false); } if (options.Upload) { if (mod.Publish()) { MySandboxGame.Log.WriteLineAndConsole(string.Format("Complete: {0}", mod.Title)); } else { success = false; MySandboxGame.Log.WriteLineAndConsole(string.Format("Error occurred: {0}", mod.Title)); } } else { if (((IMod)mod).ModId == 0) { MySandboxGame.Log.WriteLineAndConsole(string.Format("Mod not published, skipping: {0}", mod.Title)); success = false; } else { MySandboxGame.Log.WriteLineAndConsole(string.Format("Not uploading: {0}", mod.Title)); #if SE foreach (var item in mod.ModId) { mod.UpdatePreviewFileOrTags(item.Id, MyGameService.GetUGC(item.ServiceName).CreateWorkshopPublisher()); } #else mod.UpdatePreviewFileOrTags(); #endif MySandboxGame.Log.WriteLineAndConsole(string.Format("Complete: {0}", mod.Title)); } } } else { MySandboxGame.Log.WriteLineAndConsole(string.Format("Skipping {0}: {1}", type.ToString(), mod.Title)); success = false; } MySandboxGame.Log.WriteLineAndConsole(string.Empty); } return(success); }