SteamDialog.cs (8947B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // The Command & Conquer Map Editor and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // The Command & Conquer Map Editor and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 using MobiusEditor.Controls; 16 using MobiusEditor.Interface; 17 using MobiusEditor.Utility; 18 using Steamworks; 19 using System; 20 using System.Collections.Generic; 21 using System.ComponentModel; 22 using System.Diagnostics; 23 using System.Drawing; 24 using System.Drawing.Imaging; 25 using System.IO; 26 using System.Windows.Forms; 27 28 namespace MobiusEditor.Dialogs 29 { 30 public partial class SteamDialog : Form 31 { 32 private static readonly string PreviewDirectory = Path.Combine(Path.GetTempPath(), "CnCRCMapEditor"); 33 34 private readonly IGamePlugin plugin; 35 private readonly Timer statusUpdateTimer = new Timer(); 36 37 public SteamDialog(IGamePlugin plugin) 38 { 39 this.plugin = plugin; 40 41 InitializeComponent(); 42 43 visibilityComboBox.DataSource = new [] 44 { 45 new { Name = "Public", Value = ERemoteStoragePublishedFileVisibility.k_ERemoteStoragePublishedFileVisibilityPublic }, 46 new { Name = "Friends Only", Value = ERemoteStoragePublishedFileVisibility.k_ERemoteStoragePublishedFileVisibilityFriendsOnly }, 47 new { Name = "Private", Value = ERemoteStoragePublishedFileVisibility.k_ERemoteStoragePublishedFileVisibilityPrivate } 48 }; 49 50 statusUpdateTimer.Interval = 500; 51 statusUpdateTimer.Tick += StatusUpdateTimer_Tick; 52 53 Disposed += (o, e) => { (previewTxt.Tag as Image)?.Dispose(); }; 54 } 55 56 protected override void OnLoad(EventArgs e) 57 { 58 base.OnLoad(e); 59 60 titleTxt.Text = plugin.Map.SteamSection.Title; 61 descriptionTxt.Text = plugin.Map.SteamSection.Description; 62 previewTxt.Text = plugin.Map.SteamSection.PreviewFile; 63 visibilityComboBox.SelectedValue = plugin.Map.SteamSection.Visibility; 64 65 btnPublishMap.SplitWidth = (plugin.Map.SteamSection.PublishedFileId != PublishedFileId_t.Invalid.m_PublishedFileId) ? MenuButton.DefaultSplitWidth : 0; 66 67 Directory.CreateDirectory(PreviewDirectory); 68 var previewPath = Path.Combine(PreviewDirectory, "Minimap.png"); 69 plugin.Map.GenerateWorkshopPreview().ToBitmap().Save(previewPath, ImageFormat.Png); 70 71 if (plugin.Map.BasicSection.SoloMission) 72 { 73 var soloBannerPath = Path.Combine(PreviewDirectory, "SoloBanner.png"); 74 Properties.Resources.UI_CustomMissionPreviewDefault.Save(soloBannerPath, ImageFormat.Png); 75 previewTxt.Text = soloBannerPath; 76 } 77 else 78 { 79 previewTxt.Text = previewPath; 80 } 81 82 imageTooltip.SetToolTip(previewTxt, "Preview.png"); 83 84 statusUpdateTimer.Start(); 85 86 UpdateControls(); 87 } 88 89 private void StatusUpdateTimer_Tick(object sender, EventArgs e) 90 { 91 var status = SteamworksUGC.CurrentOperation?.Status; 92 if (!string.IsNullOrEmpty(status)) 93 { 94 statusLbl.Text = status; 95 } 96 } 97 98 protected override void OnClosed(EventArgs e) 99 { 100 base.OnClosed(e); 101 102 statusUpdateTimer.Stop(); 103 statusUpdateTimer.Dispose(); 104 } 105 106 protected virtual void OnPublishSuccess() 107 { 108 statusLbl.Text = "Done."; 109 EnableControls(true); 110 } 111 112 protected virtual void OnOperationFailed(string status) 113 { 114 statusLbl.Text = status; 115 EnableControls(true); 116 } 117 118 private void EnableControls(bool enable) 119 { 120 titleTxt.Enabled = enable; 121 visibilityComboBox.Enabled = enable; 122 previewTxt.Enabled = enable; 123 previewBtn.Enabled = enable; 124 descriptionTxt.Enabled = enable; 125 btnPublishMap.Enabled = enable; 126 btnClose.Enabled = enable; 127 } 128 129 private void btnGoToSteam_Click(object sender, EventArgs e) 130 { 131 var workshopUrl = SteamworksUGC.WorkshopURL; 132 if (!string.IsNullOrEmpty(workshopUrl)) 133 { 134 Process.Start(workshopUrl); 135 } 136 } 137 138 private void btnPublishMap_Click(object sender, EventArgs e) 139 { 140 if (string.IsNullOrEmpty(plugin.Map.BasicSection.Name)) 141 { 142 plugin.Map.BasicSection.Name = titleTxt.Text; 143 } 144 145 if (string.IsNullOrEmpty(plugin.Map.BasicSection.Author)) 146 { 147 plugin.Map.BasicSection.Author = SteamFriends.GetPersonaName(); 148 } 149 150 plugin.Map.SteamSection.PreviewFile = previewTxt.Text; 151 plugin.Map.SteamSection.Title = titleTxt.Text; 152 plugin.Map.SteamSection.Description = descriptionTxt.Text; 153 plugin.Map.SteamSection.Visibility = (ERemoteStoragePublishedFileVisibility)visibilityComboBox.SelectedValue; 154 155 var tempPath = Path.Combine(Path.GetTempPath(), "CnCRCMapEditorPublishUGC"); 156 Directory.CreateDirectory(tempPath); 157 foreach (var file in new DirectoryInfo(tempPath).EnumerateFiles()) file.Delete(); 158 159 var pgmPath = Path.Combine(tempPath, "MAPDATA.PGM"); 160 plugin.Save(pgmPath, FileType.PGM); 161 162 var tags = new List<string>(); 163 switch (plugin.GameType) 164 { 165 case GameType.TiberianDawn: 166 tags.Add("TD"); 167 break; 168 case GameType.RedAlert: 169 tags.Add("RA"); 170 break; 171 } 172 173 if (plugin.Map.BasicSection.SoloMission) 174 { 175 tags.Add("SinglePlayer"); 176 } 177 else 178 { 179 tags.Add("MultiPlayer"); 180 } 181 182 if (SteamworksUGC.PublishUGC(tempPath, plugin.Map.SteamSection, tags, OnPublishSuccess, OnOperationFailed)) 183 { 184 statusLbl.Text = SteamworksUGC.CurrentOperation.Status; 185 EnableControls(false); 186 } 187 } 188 189 private void previewBtn_Click(object sender, EventArgs e) 190 { 191 var ofd = new OpenFileDialog 192 { 193 AutoUpgradeEnabled = false, 194 RestoreDirectory = true, 195 Filter = "Preview Files (*.png)|*.png", 196 CheckFileExists = true, 197 InitialDirectory = Path.GetDirectoryName(previewTxt.Text), 198 FileName = Path.GetFileName(previewTxt.Text) 199 }; 200 if (!string.IsNullOrEmpty(previewTxt.Text)) 201 { 202 ofd.FileName = previewTxt.Text; 203 } 204 if (ofd.ShowDialog() == DialogResult.OK) 205 { 206 previewTxt.Text = ofd.FileName; 207 } 208 } 209 210 private void publishAsNewToolStripMenuItem_Click(object sender, EventArgs e) 211 { 212 plugin.Map.SteamSection.PublishedFileId = PublishedFileId_t.Invalid.m_PublishedFileId; 213 btnPublishMap.PerformClick(); 214 } 215 216 private void previewTxt_TextChanged(object sender, EventArgs e) 217 { 218 try 219 { 220 (previewTxt.Tag as Image)?.Dispose(); 221 222 Bitmap preview = null; 223 using (Bitmap b = new Bitmap(previewTxt.Text)) 224 { 225 preview = new Bitmap(b.Width, b.Height, b.PixelFormat); 226 using (Graphics g = Graphics.FromImage(preview)) 227 { 228 g.DrawImage(b, Point.Empty); 229 g.Flush(); 230 } 231 } 232 233 previewTxt.Tag = preview; 234 } 235 catch (Exception) 236 { 237 previewTxt.Tag = null; 238 } 239 240 UpdateControls(); 241 } 242 243 private void descriptionTxt_TextChanged(object sender, EventArgs e) 244 { 245 UpdateControls(); 246 } 247 248 private void UpdateControls() 249 { 250 btnPublishMap.Enabled = (previewTxt.Tag != null) && !string.IsNullOrEmpty(descriptionTxt.Text); 251 } 252 } 253 }