PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/MCU-EndUser/src/org/mcupdater/MainShell.java

https://gitlab.com/Slind/MCUpdater
Java | 593 lines | 466 code | 56 blank | 71 comment | 36 complexity | c85fdff77339d58bba805b6ce46c0452 MD5 | raw file
  1. package org.mcupdater;
  2. import java.io.BufferedReader;
  3. import java.io.File;
  4. import java.io.FileNotFoundException;
  5. import java.io.IOException;
  6. import java.nio.charset.StandardCharsets;
  7. import java.nio.file.Files;
  8. import java.nio.file.Path;
  9. import java.util.ArrayList;
  10. import java.util.Collection;
  11. import java.util.Iterator;
  12. import java.util.List;
  13. import java.util.Map;
  14. import java.util.logging.FileHandler;
  15. import java.util.logging.Level;
  16. import java.util.logging.Logger;
  17. import joptsimple.ArgumentAcceptingOptionSpec;
  18. import joptsimple.OptionParser;
  19. import joptsimple.OptionSet;
  20. import org.eclipse.swt.widgets.Display;
  21. import org.eclipse.swt.widgets.Shell;
  22. import org.eclipse.swt.events.SelectionEvent;
  23. import org.eclipse.swt.events.SelectionListener;
  24. import org.eclipse.swt.graphics.Rectangle;
  25. import org.eclipse.swt.SWT;
  26. import org.eclipse.swt.widgets.Composite;
  27. import org.eclipse.swt.layout.FillLayout;
  28. import org.eclipse.swt.layout.FormAttachment;
  29. import org.eclipse.swt.layout.FormData;
  30. import org.eclipse.swt.layout.FormLayout;
  31. import org.eclipse.swt.layout.GridData;
  32. import org.eclipse.swt.layout.GridLayout;
  33. import org.eclipse.swt.widgets.Button;
  34. import org.eclipse.swt.widgets.Event;
  35. import org.eclipse.swt.widgets.Group;
  36. import org.eclipse.swt.widgets.Label;
  37. import org.eclipse.swt.widgets.Listener;
  38. import org.eclipse.swt.widgets.MessageBox;
  39. import org.eclipse.swt.widgets.Sash;
  40. import org.eclipse.swt.widgets.TabFolder;
  41. import org.eclipse.swt.widgets.TabItem;
  42. import org.mcupdater.MCUConsole.LineStyle;
  43. import org.mcupdater.instance.Instance;
  44. import org.mcupdater.model.ConfigFile;
  45. import org.mcupdater.model.GenericModule;
  46. import org.mcupdater.model.ModSide;
  47. import org.mcupdater.model.Module;
  48. import org.mcupdater.model.ServerList;
  49. import org.mcupdater.mojang.AssetManager;
  50. import org.mcupdater.mojang.MinecraftVersion;
  51. import org.mcupdater.settings.Profile;
  52. import org.mcupdater.settings.Settings;
  53. import org.mcupdater.settings.SettingsManager;
  54. import org.mcupdater.translate.TranslateProxy;
  55. import org.mcupdater.util.MCUpdater;
  56. import org.mcupdater.util.ServerPackParser;
  57. import org.mcupdater.translate.Languages;
  58. import com.google.gson.Gson;
  59. import com.google.gson.GsonBuilder;
  60. public class MainShell extends MCUApp {
  61. private static MainShell INSTANCE;
  62. private Shell shell;
  63. private ServerList selected;
  64. private MCUBrowser browser;
  65. private List<Module> modList;
  66. private MCUConsole console;
  67. private MCUProgress progress;
  68. private MCUModules modules;
  69. public TranslateProxy translate;
  70. private Label lblStatus;
  71. private InstanceList iList;
  72. private MCUClientTracker tracker;
  73. private String defaultUrl;
  74. public MCULogin login;
  75. private Button btnUpdate;
  76. private Button btnLaunch;
  77. private final Display display;
  78. private MCUSettings cmpSettings;
  79. private boolean playing;
  80. private Composite cmpStatus;
  81. private Gson gson = new GsonBuilder().setPrettyPrinting().create();
  82. /**
  83. * Launch the application.
  84. * @param args
  85. */
  86. public static void main(String[] args) {
  87. try {
  88. OptionParser optParser = new OptionParser();
  89. ArgumentAcceptingOptionSpec<String> packSpec = optParser.accepts("ServerPack").withRequiredArg().ofType(String.class);
  90. ArgumentAcceptingOptionSpec<File> rootSpec = optParser.accepts("MCURoot").withRequiredArg().ofType(File.class);
  91. OptionSet options = optParser.parse(args);
  92. MCUpdater mcu = MCUpdater.getInstance(options.valueOf(rootSpec));
  93. INSTANCE = new MainShell();
  94. INSTANCE.setDefaultPack(options.valueOf(packSpec));
  95. mcu.setParent(INSTANCE);
  96. SettingsManager.getInstance();
  97. INSTANCE.open();
  98. } catch (Exception e) {
  99. e.printStackTrace();
  100. }
  101. }
  102. private MainShell() {
  103. display = Display.getDefault();
  104. this.baseLogger = Logger.getLogger("MCUpdater");
  105. baseLogger.setLevel(Level.ALL);
  106. FileHandler mcuHandler;
  107. try {
  108. mcuHandler = new FileHandler(MCUpdater.getInstance().getArchiveFolder().resolve("MCUpdater.log").toString(), 0, 3);
  109. mcuHandler.setFormatter(new FMLStyleFormatter());
  110. baseLogger.addHandler(mcuHandler);
  111. } catch (SecurityException e) {
  112. e.printStackTrace();
  113. } catch (IOException e) {
  114. e.printStackTrace();
  115. }
  116. Version.setApp(this);
  117. }
  118. private void setDefaultPack(String packUrl) {
  119. this.defaultUrl = packUrl;
  120. }
  121. /**
  122. * Open the window.
  123. */
  124. public void open() {
  125. try {
  126. translate = Languages.valueOf(Languages.getLocale()).getProxy();
  127. } catch (Exception e) {
  128. System.out.println("No translation for " + Languages.getLocale() + "!");
  129. translate = Languages.en_US.getProxy();
  130. }
  131. createContents();
  132. processSettings();
  133. getShell().open();
  134. getShell().layout();
  135. tracker = new MCUClientTracker(display, progress);
  136. int activeJobs = 0;
  137. ServerList currentSelection = null;
  138. if (SettingsManager.getInstance().getSettings().getProfiles().size() == 0) {
  139. try {
  140. Profile newProfile = LoginDialog.doLogin(getShell(), translate, "");
  141. if (newProfile.getStyle().equals("Yggdrasil")) {
  142. SettingsManager.getInstance().getSettings().addOrReplaceProfile(newProfile);
  143. SettingsManager.getInstance().getSettings().setLastProfile(newProfile.getName());
  144. if (!SettingsManager.getInstance().isDirty()) {
  145. SettingsManager.getInstance().saveSettings();
  146. }
  147. refreshProfiles();
  148. cmpSettings.reloadProfiles();
  149. login.setSelectedProfile(newProfile.getName());
  150. }
  151. } catch (Exception e) {
  152. }
  153. }
  154. boolean playState = false;
  155. while (!getShell().isDisposed()) {
  156. if (!display.readAndDispatch()) {
  157. display.sleep();
  158. }
  159. if (activeJobs != progress.getActiveCount() || currentSelection != selected || playState != isPlaying()) {
  160. currentSelection = selected;
  161. activeJobs = progress.getActiveCount();
  162. playState = isPlaying();
  163. lblStatus.setText("Active jobs: " + activeJobs);
  164. if (activeJobs > 0) {
  165. btnLaunch.setEnabled(false);
  166. } else {
  167. if (!(currentSelection == null) && !playState){
  168. btnLaunch.setEnabled(true);
  169. } else {
  170. btnLaunch.setEnabled(false);
  171. }
  172. }
  173. if (!(currentSelection == null)) {
  174. if (progress.getActiveById(currentSelection.getServerId()) > 0){
  175. btnUpdate.setEnabled(false);
  176. } else {
  177. btnUpdate.setEnabled(true);
  178. }
  179. } else {
  180. btnUpdate.setEnabled(false);
  181. }
  182. }
  183. }
  184. display.dispose();
  185. }
  186. public boolean isPlaying() {
  187. return this.playing;
  188. }
  189. public void setPlaying(boolean state) {
  190. this.playing = state;
  191. }
  192. /**
  193. * Create contents of the window.
  194. */
  195. protected void createContents() {
  196. setShell(new Shell());
  197. getShell().setSize(1175, 592);
  198. getShell().setText("MCUpdater " + Version.VERSION);
  199. getShell().setLayout(new GridLayout(1,false));
  200. getShell().addListener(SWT.RESIZE, new Listener() {
  201. @Override
  202. public void handleEvent(Event arg0) {
  203. getShell().layout();
  204. }
  205. });
  206. final Composite mainArea = new Composite(getShell(), SWT.NONE);
  207. mainArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
  208. mainArea.setLayout(new FormLayout());
  209. {
  210. final int limit = 20;
  211. final Sash sashLeft = new Sash(mainArea, SWT.VERTICAL);
  212. Group grpInstances = new Group(mainArea, SWT.NONE);
  213. grpInstances.setText(translate.instances);
  214. grpInstances.setLayout(new FillLayout());
  215. FormData grpInstancesData = new FormData();
  216. {
  217. grpInstancesData.left = new FormAttachment(0,0);
  218. grpInstancesData.right = new FormAttachment(sashLeft, 0);
  219. grpInstancesData.top = new FormAttachment(0,0);
  220. grpInstancesData.bottom = new FormAttachment(100,0);
  221. }
  222. grpInstances.setLayoutData(grpInstancesData);
  223. {
  224. /*
  225. Composite foo = new Composite(grpInstances, SWT.NONE);
  226. foo.setLayout(new RowLayout(SWT.VERTICAL));
  227. List<ServerList> list = MCUpdater.getInstance().loadServerList("http://files.mcupdater.com/example/SamplePack.xml");
  228. Collections.sort(list);
  229. for (ServerList entry : list) {
  230. Label bar = new Label(foo, SWT.NONE);
  231. bar.setText("Entry: " + entry.getName());
  232. }
  233. */
  234. iList = new InstanceList(grpInstances);
  235. //iList.setInstances(MCUpdater.getInstance().loadServerList("http://files.mcupdater.com/example/SamplePack.xml"));
  236. //iList.setInstances(MCULogic.loadServerList(defaultUrl));
  237. grpInstances.pack();
  238. }
  239. final FormData sashLeftData = new FormData();
  240. {
  241. sashLeftData.left = new FormAttachment(20, 0);
  242. sashLeftData.top = new FormAttachment(0, 0);
  243. sashLeftData.bottom = new FormAttachment(100, 0);
  244. }
  245. sashLeft.setLayoutData(sashLeftData);
  246. sashLeft.addListener(SWT.Selection, new Listener(){
  247. @Override
  248. public void handleEvent(Event e) {
  249. Rectangle sashRect = sashLeft.getBounds();
  250. Rectangle viewRect = mainArea.getClientArea();
  251. int right = viewRect.width - sashRect.width - limit;
  252. e.x = Math.max(Math.min(e.x, right), limit);
  253. if (e.x != sashRect.x) {
  254. sashLeftData.left = new FormAttachment(0, e.x);
  255. mainArea.layout();
  256. }
  257. }
  258. });
  259. final TabFolder tabFolder = new TabFolder(mainArea, SWT.NONE);
  260. final FormData grpTabData = new FormData();
  261. {
  262. grpTabData.left = new FormAttachment(sashLeft,0);
  263. grpTabData.right = new FormAttachment(100,0);
  264. grpTabData.top = new FormAttachment(0,0);
  265. grpTabData.bottom = new FormAttachment(100,0);
  266. }
  267. tabFolder.setLayoutData(grpTabData);
  268. {
  269. TabItem tbtmNews = new TabItem(tabFolder, SWT.V_SCROLL);
  270. {
  271. tbtmNews.setText(translate.news);
  272. browser = new MCUBrowser(tabFolder, SWT.NONE);
  273. tbtmNews.setControl(browser);
  274. }
  275. TabItem tbtmConsole = new TabItem(tabFolder, SWT.NONE);
  276. {
  277. tbtmConsole.setText(translate.console);
  278. console = new MCUConsole(tabFolder);
  279. tbtmConsole.setControl(console);
  280. ConsoleHandler consoleHandler = new ConsoleHandler(console);
  281. consoleHandler.setLevel(Level.INFO);
  282. baseLogger.addHandler(consoleHandler);
  283. MCUpdater.apiLogger.addHandler(consoleHandler);
  284. }
  285. TabItem tbtmSettings = new TabItem(tabFolder, SWT.NONE);
  286. {
  287. tbtmSettings.setText(translate.settings);
  288. cmpSettings = new MCUSettings(tabFolder);
  289. tbtmSettings.setControl(cmpSettings);
  290. }
  291. TabItem tbtmModules = new TabItem(tabFolder, SWT.NONE);
  292. {
  293. tbtmModules.setText(translate.modules);
  294. modules = new MCUModules(tabFolder);
  295. tbtmModules.setControl(modules);
  296. }
  297. TabItem tbtmProgress = new TabItem(tabFolder, SWT.NONE);
  298. {
  299. tbtmProgress.setText(translate.progress);
  300. progress = new MCUProgress(tabFolder);
  301. tbtmProgress.setControl(progress);
  302. }
  303. }
  304. /*
  305. Group grpModules = new Group(mainArea, SWT.NONE);
  306. grpModules.setText("Modules");
  307. final FormData grpModulesData = new FormData();
  308. {
  309. grpModulesData.left = new FormAttachment(sashRight,0);
  310. grpModulesData.right = new FormAttachment(100, 0);
  311. grpModulesData.top = new FormAttachment(0,0);
  312. grpModulesData.bottom = new FormAttachment(100,0);
  313. }
  314. grpModules.setLayoutData(grpModulesData);
  315. grpModules.setLayout(new FillLayout(SWT.VERTICAL));
  316. ScrolledComposite modScroller = new ScrolledComposite(grpModules, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
  317. modContainer = new Composite(modScroller, SWT.FILL);
  318. modContainer.setLayout(new RowLayout(SWT.VERTICAL));
  319. modScroller.setContent(modContainer);
  320. */
  321. // final FormData sashRightData = new FormData();
  322. // {
  323. // sashRightData.right = new FormAttachment(80,0);
  324. // sashRightData.top = new FormAttachment(0, 0);
  325. // sashRightData.bottom = new FormAttachment(100, 0);
  326. // }
  327. // sashRight.setLayoutData(sashRightData);
  328. // sashRight.addListener(SWT.Selection, new Listener(){
  329. // @Override
  330. // public void handleEvent(Event e) {
  331. // Rectangle sashRect = sashRight.getBounds();
  332. // Rectangle viewRect = mainArea.getClientArea();
  333. // int right = viewRect.width - sashRect.width - limit;
  334. // e.x = Math.max(Math.min(e.x, right), limit);
  335. // if (e.x != sashRect.x) {
  336. // sashRightData.right = new FormAttachment(0, e.x);
  337. // mainArea.layout();
  338. // }
  339. // }
  340. // });
  341. }
  342. cmpStatus = new Composite(getShell(), SWT.NONE);
  343. cmpStatus.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false));
  344. {
  345. cmpStatus.setLayout(new GridLayout(4, false));
  346. lblStatus = new Label(cmpStatus, SWT.NONE);
  347. lblStatus.setLayoutData(new GridData(SWT.FILL,SWT.CENTER,true,false,1,1));
  348. lblStatus.setText("Ready");
  349. login = new MCULogin(cmpStatus);
  350. login.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER,false,false,1,1));
  351. btnUpdate = new Button(cmpStatus, SWT.PUSH);
  352. btnUpdate.setEnabled(false);
  353. btnUpdate.setLayoutData(new GridData(SWT.LEFT,SWT.CENTER,false,false,1,1));
  354. btnUpdate.setText(translate.update);
  355. btnUpdate.addSelectionListener(new SelectionListener() {
  356. @Override
  357. public void widgetSelected(SelectionEvent arg0) {
  358. btnUpdate.setEnabled(false);
  359. MCUpdater.getInstance().getInstanceRoot().resolve(selected.getServerId()).toFile().mkdirs();
  360. Instance instData;
  361. final Path instanceFile = MCUpdater.getInstance().getInstanceRoot().resolve(selected.getServerId()).resolve("instance.json");
  362. try {
  363. BufferedReader reader = Files.newBufferedReader(instanceFile, StandardCharsets.UTF_8);
  364. instData = gson.fromJson(reader, Instance.class);
  365. reader.close();
  366. } catch (IOException e) {
  367. e.printStackTrace();
  368. instData = new Instance();
  369. }
  370. final List<GenericModule> selectedMods = new ArrayList<GenericModule>();
  371. final List<ConfigFile> selectedConfigs = new ArrayList<ConfigFile>();
  372. Iterator<ModuleCheckbox> it = modules.getModules().iterator();
  373. while (it.hasNext()){
  374. ModuleCheckbox entry = it.next();
  375. System.out.println("Module: " + entry.getModule().getName());
  376. if (entry.isSelected()) {
  377. selectedMods.add(entry.getModule());
  378. if (entry.getModule().hasConfigs()){
  379. selectedConfigs.addAll(entry.getModule().getConfigs());
  380. }
  381. if (entry.getModule().hasSubmodules()){
  382. selectedMods.addAll(entry.getModule().getSubmodules());
  383. }
  384. }
  385. if (!entry.getModule().getRequired()) {
  386. instData.setModStatus(entry.getModule().getId(), entry.isSelected());
  387. }
  388. }
  389. // try {
  390. // if (!instanceFile.toFile().exists()) { instanceFile.toFile().createNewFile(); }
  391. // instData.load(Files.newInputStream(instanceFile));
  392. // } catch (IOException e1) {
  393. // //baseLogger.log(Level.SEVERE, "I/O error", e1);
  394. // e1.printStackTrace();
  395. // }
  396. try {
  397. MCUpdater.getInstance().installMods(selected , selectedMods, selectedConfigs, false, instData, ModSide.CLIENT);
  398. } catch (FileNotFoundException e) {
  399. // TODO Auto-generated catch block
  400. e.printStackTrace();
  401. }
  402. }
  403. @Override
  404. public void widgetDefaultSelected(SelectionEvent arg0) { widgetSelected(arg0); }
  405. });
  406. btnLaunch = new Button(cmpStatus, SWT.PUSH);
  407. btnLaunch.setEnabled(false);
  408. btnLaunch.setLayoutData(new GridData(SWT.LEFT,SWT.CENTER,false,false,1,1));
  409. btnLaunch.setText(translate.launchMinecraft);
  410. btnLaunch.addSelectionListener(new SelectionListener()
  411. {
  412. @Override
  413. public void widgetDefaultSelected(SelectionEvent arg0) {
  414. widgetSelected(arg0);
  415. }
  416. @Override
  417. public void widgetSelected(SelectionEvent arg0) {
  418. btnLaunch.setEnabled(false);
  419. Profile launchProfile = login.getSelectedProfile();
  420. if (!(launchProfile == null)) {
  421. SettingsManager.getInstance().getSettings().setLastProfile(launchProfile.getName());
  422. SettingsManager.getInstance().getSettings().findProfile(launchProfile.getName()).setLastInstance(selected.getServerId());
  423. if (!SettingsManager.getInstance().isDirty()) {
  424. SettingsManager.getInstance().saveSettings();
  425. }
  426. try {
  427. MCULogic.doLaunch(selected, modules.getModules(), launchProfile);
  428. } catch (Exception e) {
  429. MessageBox msg = new MessageBox(getShell(), SWT.ICON_WARNING);
  430. msg.setMessage(e.getMessage() + "\n\nNote: An authentication error can occur if your profile is out of sync with Mojang's servers.\nRe-add your profile in the Settings tab to resync with Mojang.");
  431. log(e.getMessage());
  432. msg.open();
  433. }
  434. }
  435. }
  436. });
  437. }
  438. }
  439. public void changeSelectedInstance(ServerList entry) {
  440. this.selected = entry;
  441. browser.setUrl(selected.getNewsUrl());
  442. modList = ServerPackParser.loadFromURL(selected.getPackUrl(), selected.getServerId());
  443. Instance instData = new Instance();
  444. final Path instanceFile = MCUpdater.getInstance().getInstanceRoot().resolve(entry.getServerId()).resolve("instance.json");
  445. try {
  446. BufferedReader reader = Files.newBufferedReader(instanceFile, StandardCharsets.UTF_8);
  447. instData = gson.fromJson(reader, Instance.class);
  448. reader.close();
  449. } catch (IOException e) {
  450. MainShell.getInstance().baseLogger.log(Level.WARNING, "instance.json file not found.");
  451. }
  452. refreshModList(instData.getOptionalMods());
  453. }
  454. private void refreshModList(Map<String, Boolean> optionalSelections) {
  455. modules.reload(modList, optionalSelections);
  456. }
  457. public static MainShell getInstance() {
  458. return INSTANCE;
  459. }
  460. public void refreshInstances() {
  461. iList.setInstances(MCULogic.loadServerList(defaultUrl));
  462. }
  463. @Override
  464. public void setStatus(String string) {
  465. // TODO Auto-generated method stub
  466. //lblStatus.setText(string);
  467. }
  468. @Override
  469. public void log(String msg) {
  470. baseLogger.info(msg);
  471. }
  472. @Override
  473. public boolean requestLogin() {
  474. // TODO Auto-generated method stub
  475. return false;
  476. }
  477. @Override
  478. public void addServer(ServerList entry) {
  479. // TODO Auto-generated method stub
  480. }
  481. @Override
  482. public void addProgressBar(String title, String parent) {
  483. progress.addProgressBar(title, parent);
  484. }
  485. @Override
  486. public DownloadQueue submitNewQueue(String queueName, String parent, Collection<Downloadable> files, File basePath, File cachePath) {
  487. progress.addProgressBar(queueName, parent);
  488. if (login.getSelectedProfile() != null) {
  489. return new DownloadQueue(queueName, parent, tracker, files, basePath, cachePath, login.getSelectedProfile().getName());
  490. } else {
  491. return new DownloadQueue(queueName, parent, tracker, files, basePath, cachePath);
  492. }
  493. }
  494. @Override
  495. public DownloadQueue submitAssetsQueue(String queueName, String parent, MinecraftVersion version) {
  496. progress.addProgressBar(queueName, parent);
  497. return AssetManager.downloadAssets(queueName, parent, MCUpdater.getInstance().getArchiveFolder().resolve("assets").toFile(), tracker, version);
  498. }
  499. public void refreshProfiles() {
  500. login.refreshProfiles(SettingsManager.getInstance().getSettings());
  501. cmpStatus.layout();
  502. }
  503. public void processSettings() {
  504. Settings settings = SettingsManager.getInstance().getSettings();
  505. MCUpdater.getInstance().setInstanceRoot(new File(settings.getInstanceRoot()).toPath());
  506. MCUpdater.getInstance().getInstanceRoot().toFile().mkdirs();
  507. refreshProfiles();
  508. refreshInstances();
  509. login.setSelectedProfile(settings.getLastProfile());
  510. }
  511. public void setSelectedInstance(String lastInstance) {
  512. iList.changeSelection(lastInstance);
  513. }
  514. public String getDefaultPack() {
  515. return this.defaultUrl;
  516. }
  517. public Display getDisplay() {
  518. return display;
  519. }
  520. public Shell getShell() {
  521. return shell;
  522. }
  523. public void setShell(Shell shell) {
  524. this.shell = shell;
  525. }
  526. public void consoleWrite(final String line) {
  527. display.syncExec(new Runnable() {
  528. @Override
  529. public void run() {
  530. console.appendLine(line, LineStyle.NORMAL);
  531. }
  532. });
  533. }
  534. public ServerList getSelectedInstance() {
  535. return this.selected;
  536. }
  537. }