├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── license-definitions.xml
├── pom.xml
└── src
└── main
├── java
└── com
│ └── github
│ └── pemapmodder
│ └── pocketminegui
│ ├── PocketMineGUI.java
│ ├── gui
│ ├── server
│ │ ├── ConsolePanel.java
│ │ ├── InternalMessage.java
│ │ ├── LineReader.java
│ │ ├── ServerLifetime.java
│ │ └── ServerMainActivity.java
│ └── startup
│ │ ├── ChooseServerActivity.java
│ │ ├── config
│ │ ├── ServerOptionsActivity.java
│ │ └── adaptor
│ │ │ ├── CheckBoxOptionAdaptor.java
│ │ │ ├── NumberFieldAdaptor.java
│ │ │ └── OptionAdaptor.java
│ │ └── installer
│ │ ├── FetchVersionsThread.java
│ │ ├── InstallPHPThread.java
│ │ ├── InstallServerActivity.java
│ │ ├── Release.java
│ │ ├── ReleaseType.java
│ │ └── cards
│ │ ├── ChooseLocationCard.java
│ │ ├── ChooseVersionCard.java
│ │ ├── DownloadProgressCard.java
│ │ ├── PhpInstallerCard.java
│ │ └── ServerSetupCard.java
│ ├── lib
│ ├── Activity.java
│ ├── JNumberFilter.java
│ └── card
│ │ ├── Card.java
│ │ └── CardActivity.java
│ └── utils
│ ├── AsyncTask.java
│ ├── GetUrlThread.java
│ ├── NonBlockingANSIReader.java
│ ├── NonBlockingBufferedReader.java
│ ├── Ring.java
│ ├── TerminalCode.java
│ └── Utils.java
└── resources
├── plugins
└── adaptor.php
└── pocketmine.yml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Java template
3 | *.class
4 |
5 | # Mobile Tools for Java (J2ME)
6 | .mtj.tmp/
7 |
8 | # Package Files #
9 | *.jar
10 | *.war
11 | *.ear
12 |
13 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
14 | hs_err_pid*
15 | ### JetBrains template
16 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
17 |
18 | *.iml
19 |
20 | ## Directory-based project format:
21 | .idea/
22 | # if you remove the above rule, at least ignore the following:
23 |
24 | # User-specific stuff:
25 | # .idea/workspace.xml
26 | # .idea/tasks.xml
27 | # .idea/dictionaries
28 |
29 | # Sensitive or high-churn files:
30 | # .idea/dataSources.ids
31 | # .idea/dataSources.xml
32 | # .idea/sqlDataSources.xml
33 | # .idea/dynamic.xml
34 | # .idea/uiDesigner.xml
35 |
36 | # Gradle:
37 | # .idea/gradle.xml
38 | # .idea/libraries
39 |
40 | # Mongo Explorer plugin:
41 | # .idea/mongoSettings.xml
42 |
43 | ## File-based project format:
44 | *.ipr
45 | *.iws
46 |
47 | ## Plugin-specific files:
48 |
49 | # IntelliJ
50 | /out/
51 |
52 | # mpeltonen/sbt-idea plugin
53 | .idea_modules/
54 |
55 | # JIRA plugin
56 | atlassian-ide-plugin.xml
57 |
58 | # Crashlytics plugin (for Android Studio and IntelliJ)
59 | com_crashlytics_export_strings.xml
60 | crashlytics.properties
61 | crashlytics-build.properties
62 | ### NetBeans template
63 | nbproject/private/
64 | build/
65 | nbbuild/
66 | dist/
67 | nbdist/
68 | nbactions.xml
69 | nb-configuration.xml
70 | .nb-gradle/
71 | ### Maven template
72 | target/
73 | pom.xml.tag
74 | pom.xml.releaseBackup
75 | pom.xml.versionsBackup
76 | pom.xml.next
77 | release.properties
78 | dependency-reduced-pom.xml
79 | buildNumber.properties
80 | .mvn/timing.properties
81 | ### Eclipse template
82 | *.pydevproject
83 | .metadata
84 | .gradle
85 | test/bin/
86 | tmp/
87 | *.tmp
88 | *.bak
89 | *.swp
90 | *~.nib
91 | local.properties
92 | .settings/
93 | .loadpath
94 |
95 | # Eclipse Core
96 | .project
97 |
98 | # External tool builders
99 | .externalToolBuilders/
100 |
101 | # Locally stored "Eclipse launch configurations"
102 | *.launch
103 |
104 | # CDT-specific
105 | .cproject
106 |
107 | # JDT-specific (Eclipse Java Development Tools)
108 | .classpath
109 |
110 | # Java annotation processor (APT)
111 | .factorypath
112 |
113 | # PDT-specific
114 | .buildpath
115 |
116 | # sbteclipse plugin
117 | .target
118 |
119 | # TeXlipse plugin
120 | .texlipse
121 |
122 | # Custom
123 | PocketMine-MP/
124 | test/
125 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | sudo: false
3 | install:
4 | - (mvn license:check package || echo) > /dev/null # pre-run the script to install plugins
5 | - rm -r target # clean directory
6 | script: mvn license:check package
7 | jdk: [oraclejdk8]
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
167 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PocketMine-GUI [](https://travis-ci.org/PEMapModder/PocketMine-GUI)
2 |
3 | [](https://gitter.im/PEMapModder/PocketMine-GUI?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4 | Java Swing-based PocketMine-MP GUI
5 |
6 | Compiling/Running
7 | ===
8 | * Install maven
9 | * Run these maven goals:
10 | * `package` - compiles the project and packs classes into a jar
11 | * `exec:java` - executes the jar
12 |
13 | For debugging, running `mvn package exec:java` every test is recommended.
14 |
--------------------------------------------------------------------------------
/license-definitions.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
23 | /*
24 | *
25 | */
26 | (\s|\t)*/\*.*$
27 | .*\*/(\s|\t)*$
28 | false
29 | true
30 | false
31 |
32 |
33 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
24 | 4.0.0
25 |
26 | com.github.pemapmodder
27 | PocketMine-GUI
28 | 1.0-SNAPSHOT
29 |
30 |
31 |
32 |
33 | org.projectlombok
34 | lombok
35 | 1.16.6
36 | provided
37 |
38 |
39 |
40 | org.apache.commons
41 | commons-lang3
42 | 3.3.2
43 |
44 |
45 |
46 | com.googlecode.json-simple
47 | json-simple
48 | 1.1
49 |
50 |
51 |
52 | commons-io
53 | commons-io
54 | 2.4
55 |
56 |
57 |
58 | org.apache.commons
59 | commons-compress
60 | 1.10
61 |
62 |
63 |
64 | commons-collections
65 | commons-collections
66 | 3.2.2
67 |
68 |
69 |
70 |
71 | org.json
72 | json
73 | 20150729
74 |
75 |
76 |
77 | org.yaml
78 | snakeyaml
79 | 1.16
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | org.apache.maven.plugins
88 | maven-compiler-plugin
89 | 3.3
90 |
91 | 1.8
92 | 1.8
93 | UTF-8
94 |
95 |
96 |
97 |
98 | org.apache.maven.plugins
99 | maven-javadoc-plugin
100 | 2.10.3
101 |
102 | UTF-8
103 |
104 |
105 |
106 |
107 | com.mycila
108 | license-maven-plugin
109 | 2.11
110 |
111 | com/mycila/maven/plugin/license/templates/LGPL-3.txt
112 |
113 |
114 | license-definitions.xml
115 |
116 |
117 |
118 | **/README
119 | **/LICENSE
120 | src/test/resources/**
121 | src/main/resources/**
122 | PocketMine-MP/**
123 | test/**
124 |
125 |
126 |
127 |
128 | package
129 |
130 | check
131 |
132 |
133 |
134 |
135 |
136 |
137 | org.apache.maven.plugins
138 | maven-shade-plugin
139 | 2.3
140 |
141 |
142 |
143 | package
144 |
145 | shade
146 |
147 |
148 |
149 |
150 |
152 | com.github.pemapmodder.pocketminegui.PocketMineGUI
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 | org.codehaus.mojo
162 | exec-maven-plugin
163 | 1.2.1
164 |
165 | com.github.pemapmodder.pocketminegui.PocketMineGUI
166 |
167 |
168 |
169 |
170 | java
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/PocketMineGUI.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | import com.github.pemapmodder.pocketminegui.gui.startup.ChooseServerActivity;
21 | import com.github.pemapmodder.pocketminegui.lib.Activity;
22 |
23 | /**
24 | * Entry class to the program
25 | */
26 | public class PocketMineGUI{
27 | public static Activity CURRENT_ROOT_ACTIVITY = null;
28 |
29 | public static void main(String[] args){
30 | new ChooseServerActivity().init();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/server/ConsolePanel.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.server;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | import com.github.pemapmodder.pocketminegui.utils.NonBlockingANSIReader;
21 | import com.github.pemapmodder.pocketminegui.utils.Ring;
22 | import com.github.pemapmodder.pocketminegui.utils.TerminalCode;
23 | import org.apache.commons.lang3.StringUtils;
24 |
25 | import javax.swing.*;
26 | import javax.swing.text.BadLocationException;
27 | import javax.swing.text.Element;
28 | import javax.swing.text.Style;
29 | import javax.swing.text.html.HTMLDocument;
30 | import java.awt.Color;
31 | import java.awt.Dimension;
32 | import java.awt.GridBagConstraints;
33 | import java.awt.GridBagLayout;
34 | import java.awt.event.KeyAdapter;
35 | import java.awt.event.KeyEvent;
36 | import java.io.IOException;
37 |
38 | public class ConsolePanel extends JPanel{
39 | private final static int BUFFER_SIZE = 100;
40 | private final ServerMainActivity activity;
41 | private final JLabel title;
42 | private final JEditorPane stdout;
43 | private final HTMLDocument doc;
44 | private final Element para;
45 | private final Ring consoleBuffer = new Ring<>(new String[BUFFER_SIZE]);
46 |
47 | public ConsolePanel(ServerMainActivity activity){
48 | this.activity = activity;
49 | setLayout(new GridBagLayout());
50 | setBorder(BorderFactory.createEmptyBorder(20, 10, 20, 10));
51 | title = new JLabel("PocketMine-MP");
52 | GridBagConstraints c = new GridBagConstraints();
53 | c.anchor = GridBagConstraints.CENTER;
54 | c.fill = GridBagConstraints.HORIZONTAL;
55 | c.weighty = 0.0;
56 | add(title, c);
57 | stdout = new JEditorPane(){
58 | @Override
59 | public boolean getScrollableTracksViewportHeight(){
60 | return true;
61 | }
62 |
63 | @Override
64 | public boolean getScrollableTracksViewportWidth(){
65 | return true;
66 | }
67 | };
68 | stdout.setContentType("text/html");
69 | stdout.setText("
" +
70 | "
");
71 | doc = (HTMLDocument) stdout.getDocument();
72 | para = doc.getElement("p");
73 | JScrollPane scrollPane = new JScrollPane();
74 | stdout.setEditable(false);
75 | // People NEED to see this to feel happy
76 | stdout.setForeground(Color.WHITE);
77 | stdout.setBackground(Color.BLACK);
78 | Style style = doc.getStyleSheet().addStyle(null, null);
79 | doc.setParagraphAttributes(para.getStartOffset(), 1, style, true);
80 | scrollPane.getViewport().add(stdout);
81 | scrollPane.setMinimumSize(new Dimension(200, 200));
82 | scrollPane.setPreferredSize(new Dimension(500, 400));
83 | scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
84 | c.gridy = 1;
85 | c.weightx = 0.9;
86 | c.weighty = 0.0;
87 | c.fill = GridBagConstraints.BOTH;
88 | c.anchor = GridBagConstraints.NORTHWEST;
89 | add(scrollPane, c);
90 | JTextField stdin = new JTextField();
91 | stdin.addKeyListener(new MyKeyAdapter(stdin, activity));
92 | c.gridy = 2;
93 | c.weighty = 0.0;
94 | c.fill = GridBagConstraints.HORIZONTAL;
95 | add(stdin, c);
96 | Timer timer = new Timer(50, e -> updateConsole());
97 | timer.start();
98 | }
99 |
100 | private void updateConsole(){
101 | NonBlockingANSIReader reader = activity.getStdoutBuffered();
102 | if(reader == null){
103 | return;
104 | }
105 | NonBlockingANSIReader.Entry entry;
106 | while((entry = reader.nextOutput()) != null){
107 | if(entry.getType() == NonBlockingANSIReader.EntryType.TITLE){
108 | title.setText(entry.getLine());
109 | continue;
110 | }
111 | if(entry.getType() == NonBlockingANSIReader.EntryType.PMGUI){
112 | activity.getLifetime().handlePluginMessage(new InternalMessage(entry.getLine()));
113 | continue;
114 | }
115 | String line = TerminalCode.toHTML(entry.getLine());
116 | String text = stdout.getText();
117 | consoleBuffer.add(line);
118 |
119 | try{
120 | doc.setInnerHTML(para, StringUtils.join(consoleBuffer, " "));
121 | }catch(BadLocationException | IOException e){
122 | e.printStackTrace();
123 | }
124 |
125 | String clean = TerminalCode.clean(entry.getLine());
126 | activity.getLifetime().handleConsoleOutput(clean);
127 | }
128 | }
129 |
130 | private static class MyKeyAdapter extends KeyAdapter{
131 | private final JTextField stdin;
132 | private final ServerMainActivity activity;
133 | Ring consoleLog = new Ring<>(new String[50]);
134 | int neg = 0;
135 | String tmpText = "";
136 |
137 | public MyKeyAdapter(JTextField stdin, ServerMainActivity activity){
138 | this.stdin = stdin;
139 | this.activity = activity;
140 | }
141 |
142 | @Override
143 | public void keyPressed(KeyEvent e){
144 | String newText = null;
145 | if(e.getKeyCode() == KeyEvent.VK_ENTER){
146 | if(activity.getProcess() == null){
147 | return;
148 | }
149 | try{
150 | String line = stdin.getText();
151 | activity.getStdin().write(line.concat(System.lineSeparator()).getBytes());
152 | newText = "";
153 | neg = 0;
154 | consoleLog.add(line);
155 | }catch(IOException e1){
156 | e1.printStackTrace();
157 | return;
158 | }
159 | }else if(e.getKeyCode() == KeyEvent.VK_UP || e.getKeyChar() == KeyEvent.VK_KP_UP){
160 | ++neg;
161 | if(neg == 1){
162 | tmpText = stdin.getText();
163 | }
164 | try{
165 | newText = consoleLog.get(consoleLog.getSize() - neg);
166 | }catch(IndexOutOfBoundsException e1){
167 | --neg;
168 | return;
169 | }
170 | }else if(e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_KP_DOWN){
171 | if(neg <= 0){
172 | neg = 0;
173 | return;
174 | }
175 | --neg;
176 | if(neg == 0){
177 | newText = tmpText;
178 | }else{
179 | newText = consoleLog.get(consoleLog.getSize() - neg);
180 | }
181 | }
182 | if(newText != null){
183 | stdin.setText(newText);
184 | }
185 | }
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/server/InternalMessage.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.server;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | import lombok.Getter;
21 | import lombok.RequiredArgsConstructor;
22 | import org.json.JSONObject;
23 |
24 | @Getter
25 | public class InternalMessage{
26 | @RequiredArgsConstructor
27 | @Getter
28 | public enum Type{
29 | SERVER_STARTED(0),
30 | PLAYER_JOIN(1),
31 | PLAYER_QUIT(2),
32 | PLUGIN_DISABLED(3);
33 |
34 | private final int type;
35 |
36 | public static Type get(int id){
37 | for(Type type : values()){
38 | if(type.type == id){
39 | return type;
40 | }
41 | }
42 | return null;
43 | }
44 | }
45 |
46 | private final Type type;
47 | private final JSONObject data;
48 |
49 | public InternalMessage(String line){
50 | line = line.substring(8);
51 | int index = line.indexOf(':');
52 | type = Type.get(Integer.parseInt(line.substring(0, index)));
53 | String json = line.substring(index + 1);
54 | data = new JSONObject(json);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/server/LineReader.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.server;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | import lombok.RequiredArgsConstructor;
21 |
22 | @RequiredArgsConstructor
23 | public class LineReader{
24 | private final String src;
25 | private int pointer = 0;
26 |
27 | public void expect(String string){
28 | if(!src.substring(pointer, pointer + string.length()).equals(string)){
29 | throw new RuntimeException("Unexpected console output");
30 | }
31 | pointer += string.length();
32 | }
33 |
34 | public void expect(char ch){
35 | if(src.charAt(pointer) != ch){
36 | throw new RuntimeException("Unexpected console output");
37 | }
38 | ++pointer;
39 | }
40 |
41 | public String readBefore(char until){
42 | int pos = src.indexOf(until, pointer);
43 | String substring = src.substring(pointer, pos);
44 | pointer = pos;
45 | return substring;
46 | }
47 |
48 | public String readThrough(char until){
49 | int pos = src.indexOf(until, pointer);
50 | String substring = src.substring(pointer, pos);
51 | pointer = pos + 1;
52 | return substring;
53 | }
54 |
55 | public String readUntil(char until){
56 | int pos = src.indexOf(until, pointer);
57 | String substring = src.substring(pointer, pos + 1);
58 | pointer = pos + 1;
59 | return substring;
60 | }
61 |
62 | public String readRemaining(){
63 | String substring = src.substring(pointer);
64 | pointer = src.length();
65 | return substring;
66 | }
67 |
68 | public boolean eof(){
69 | return pointer >= src.length();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/server/ServerLifetime.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.server;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | import com.github.pemapmodder.pocketminegui.gui.server.ServerMainActivity.ServerState;
21 | import lombok.Getter;
22 | import lombok.RequiredArgsConstructor;
23 |
24 | import javax.swing.JButton;
25 | import java.awt.event.ActionEvent;
26 | import java.io.IOException;
27 |
28 | @RequiredArgsConstructor
29 | public class ServerLifetime{
30 | @Getter private final ServerMainActivity activity;
31 | @Getter private ServerState state = ServerState.STATE_STOPPED;
32 |
33 | public void nextState(){
34 | JButton button = activity.getStartStopButton();
35 | if(state == ServerState.STATE_STOPPED){
36 | state = ServerState.STATE_STARTING;
37 | button.setText(state.getButtonName());
38 | button.setEnabled(false);
39 | }else if(state == ServerState.STATE_STARTING){
40 | state = ServerState.STATE_RUNNING;
41 | button.setText(state.getButtonName());
42 | button.setEnabled(true);
43 | }else if(state == ServerState.STATE_RUNNING){
44 | setStateStopping();
45 | }
46 | }
47 |
48 | public void setStateStopping(){
49 | state = ServerState.STATE_STOPPING;
50 | JButton button = activity.getStartStopButton();
51 | button.setText(state.getButtonName());
52 | button.setEnabled(false);
53 | }
54 |
55 | public void listen(ActionEvent e){
56 | if(state == ServerState.STATE_STOPPED){
57 | nextState();
58 | activity.startServer();
59 | }else if(state == ServerState.STATE_RUNNING){
60 | nextState();
61 | try{
62 | activity.getStdin().write("stop".concat(System.lineSeparator()).getBytes());
63 | }catch(IOException e1){
64 | e1.printStackTrace();
65 | }
66 | }
67 | }
68 |
69 | public void handleConsoleOutput(String clean){
70 | LineReader r = new LineReader(clean.trim());
71 | try{
72 | r.expect('[');
73 | int hour = Integer.parseInt(r.readThrough(':'));
74 | int minute = Integer.parseInt(r.readThrough(':'));
75 | int second = Integer.parseInt(r.readThrough(']'));
76 | r.readUntil('[');
77 | String thread = r.readThrough('/');
78 | String type = r.readThrough(']');
79 | r.expect(": ");
80 | String rest = r.readRemaining();
81 | // TODO message filtering
82 | }catch(RuntimeException e){
83 | System.err.println("Warning: Invalid console output: " + clean);
84 | e.printStackTrace();
85 | }
86 | }
87 |
88 | public void handlePluginMessage(InternalMessage message){
89 | switch(message.getType()){
90 | case SERVER_STARTED:
91 | if(state == ServerState.STATE_STARTING){
92 | nextState();
93 | }else{
94 | new RuntimeException("Unexpected SERVER_STARTED message received while server is in " + state.name()).printStackTrace();
95 | }
96 | break;
97 | case PLUGIN_DISABLED:
98 | setStateStopping();
99 | break;
100 | case PLAYER_JOIN:
101 | // TODO: handle
102 | break;
103 | case PLAYER_QUIT:
104 | // TODO: handle
105 | break;
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/server/ServerMainActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.server;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | import com.github.pemapmodder.pocketminegui.lib.Activity;
21 | import com.github.pemapmodder.pocketminegui.utils.NonBlockingANSIReader;
22 | import lombok.Getter;
23 | import org.apache.commons.io.IOUtils;
24 |
25 | import javax.swing.JButton;
26 | import javax.swing.JMenu;
27 | import javax.swing.JMenuBar;
28 | import java.awt.GridBagConstraints;
29 | import java.awt.GridBagLayout;
30 | import java.awt.event.KeyEvent;
31 | import java.io.*;
32 |
33 | public class ServerMainActivity extends Activity{
34 | @Getter private Process process;
35 | @Getter private OutputStream stdin;
36 | @Getter private InputStream stdout;
37 | @Getter private NonBlockingANSIReader stdoutBuffered;
38 |
39 | // @Getter private ServerState serverState = ServerState.STATE_STOPPED;
40 | @Getter private ServerLifetime lifetime;
41 | private File home;
42 |
43 | private File phpBinaries, pmEntry;
44 | @Getter private JButton startStopButton;
45 | @Getter private ConsolePanel consolePanel;
46 |
47 | public ServerMainActivity(File home, File phpBinaries){
48 | super("PocketMine-GUI @ " + home.getAbsolutePath());
49 | this.home = home;
50 | this.phpBinaries = phpBinaries;
51 | pmEntry = new File(home, "PocketMine-MP.phar");
52 | if(!pmEntry.isFile()){
53 | pmEntry = new File(home, "src");
54 | if(!pmEntry.isDirectory()){
55 | throw new RuntimeException("No PocketMine entry detected");
56 | }
57 | pmEntry = new File(pmEntry, "pocketmine/PocketMine.php");
58 | }
59 | File pluginPath = new File(home, "plugins/.pmgui.adaptor.php");
60 | pluginPath.getParentFile().mkdirs();
61 | try{
62 | IOUtils.copy(getClass().getClassLoader().getResourceAsStream("plugins/adaptor.php"), new FileOutputStream(pluginPath));
63 | }catch(IOException e){
64 | e.printStackTrace();
65 | }
66 | }
67 |
68 | @Override
69 | protected void onStart(){
70 | lifetime = new ServerLifetime(this);
71 |
72 | // setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
73 | setLayout(new GridBagLayout());
74 | JMenuBar bar = new JMenuBar();
75 | JMenu serverMenu = new JMenu("Server");
76 | serverMenu.setMnemonic(KeyEvent.VK_S);
77 | JMenu playerMenu = new JMenu("Players");
78 | playerMenu.setMnemonic(KeyEvent.VK_P);
79 | bar.add(serverMenu);
80 | bar.add(playerMenu);
81 | setJMenuBar(bar);
82 |
83 | startStopButton = new JButton("Start");
84 | startStopButton.addActionListener(lifetime::listen);
85 | GridBagConstraints constr = new GridBagConstraints();
86 | constr.gridx = 0;
87 | constr.gridy = 0;
88 | constr.fill = GridBagConstraints.VERTICAL;
89 | constr.weighty = 0.02;
90 | constr.weightx = 0.1;
91 | add(startStopButton, constr);
92 | constr.gridx = 1;
93 | constr.gridy = 1;
94 | constr.fill = GridBagConstraints.BOTH;
95 | constr.weightx = 0.8;
96 | constr.weighty = 0.9;
97 | add(consolePanel = new ConsolePanel(this), constr);
98 | }
99 |
100 | boolean startServer(){
101 | try{
102 | System.err.println("Starting server: " + phpBinaries.getAbsolutePath() + " " + pmEntry.getAbsolutePath());
103 | setProcess(new ProcessBuilder
104 | (phpBinaries.getAbsolutePath(), pmEntry.getAbsolutePath(),
105 | "--enable-ansi", "--disable-readline", "--disable-wizard", "--pmgui.enabled=1")
106 | .directory(home)
107 | .redirectErrorStream(true)
108 | .start());
109 | }catch(IOException e){
110 | e.printStackTrace();
111 | }
112 | return true;
113 | }
114 |
115 | public void setProcess(Process process){
116 | this.process = process;
117 | stdin = process.getOutputStream();
118 | stdout = process.getInputStream();
119 | stdoutBuffered = new NonBlockingANSIReader(stdout);
120 | stdoutBuffered.start();
121 | }
122 |
123 | @Override
124 | public void pack(){
125 | super.pack();
126 | setExtendedState(MAXIMIZED_BOTH);
127 | }
128 |
129 | public enum ServerState{
130 | STATE_STOPPED("Start"),
131 | STATE_STARTING("Starting..."),
132 | STATE_RUNNING("Stop"),
133 | STATE_STOPPING("Stopping...");
134 |
135 | @Getter private String buttonName;
136 |
137 | ServerState(String buttonName){
138 | this.buttonName = buttonName;
139 | }
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/startup/ChooseServerActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.startup;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | import com.github.pemapmodder.pocketminegui.gui.server.ServerMainActivity;
21 | import com.github.pemapmodder.pocketminegui.gui.startup.installer.InstallServerActivity;
22 | import com.github.pemapmodder.pocketminegui.lib.Activity;
23 | import com.github.pemapmodder.pocketminegui.utils.Utils;
24 |
25 | import javax.swing.*;
26 | import java.awt.Font;
27 | import java.awt.GridLayout;
28 | import java.awt.event.ActionEvent;
29 | import java.awt.event.ActionListener;
30 | import java.io.File;
31 |
32 | import static com.github.pemapmodder.pocketminegui.utils.Utils.OperatingSystem.WINDOWS;
33 | import static com.github.pemapmodder.pocketminegui.utils.Utils.exec;
34 | import static com.github.pemapmodder.pocketminegui.utils.Utils.validatePhpBinaries;
35 | import static javax.swing.JFileChooser.APPROVE_OPTION;
36 | import static javax.swing.JFileChooser.CANCEL_OPTION;
37 | import static javax.swing.JFileChooser.DIRECTORIES_ONLY;
38 | import static javax.swing.JFileChooser.ERROR_OPTION;
39 | import static javax.swing.JFileChooser.FILES_ONLY;
40 | import static javax.swing.JOptionPane.ERROR_MESSAGE;
41 | import static javax.swing.JOptionPane.WARNING_MESSAGE;
42 | import static javax.swing.JOptionPane.showMessageDialog;
43 |
44 | public class ChooseServerActivity extends Activity{
45 | public ChooseServerActivity(){
46 | super("PocketMine-GUI");
47 | }
48 |
49 | @Override
50 | protected void onStart(){
51 | setLayout(new GridLayout(3, 1));
52 | JLabel titleLabel = new JLabel("PocketMine-GUI");
53 | titleLabel.setFont(new Font("Helvetica", Font.BOLD, 24));
54 | titleLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
55 | titleLabel.setHorizontalAlignment(SwingConstants.CENTER);
56 | add(titleLabel);
57 | JButton chooseServer = new JButton("Choose server directory");
58 | chooseServer.addActionListener(new ChooseServerOnClickListener());
59 | add(chooseServer);
60 | JButton installServer = new JButton("Install server into new directory");
61 | installServer.addActionListener(new InstallServerOnClickListener());
62 | add(installServer);
63 | }
64 |
65 | private class ChooseServerOnClickListener implements ActionListener{
66 | @Override
67 | public void actionPerformed(ActionEvent e){
68 | JFileChooser chooser = new JFileChooser(new File("."));
69 | chooser.setFileSelectionMode(DIRECTORIES_ONLY);
70 | int ret = chooser.showOpenDialog(ChooseServerActivity.this);
71 | if(ret == CANCEL_OPTION || ret == ERROR_OPTION){
72 | return;
73 | }
74 | File home = chooser.getSelectedFile();
75 | if(!home.isDirectory()){
76 | showMessageDialog(ChooseServerActivity.this, "Not a directory!",
77 | "Invalid selection", ERROR_MESSAGE);
78 | return;
79 | }
80 | if(!new File(home, "PocketMine-MP.phar").isFile() && !new File(home, "src").isDirectory()){
81 | showMessageDialog(ChooseServerActivity.this, "Could not find a phar or " +
82 | "source installation of PocketMine-MP in directory! " +
83 | "Please click the \"Install server into new directory\" button if " +
84 | "you wish to install a server there instead.", "Invalid selection", ERROR_MESSAGE);
85 | return;
86 | }
87 | File phpBinaries = new File(home, "bin/php/php.exe");
88 | if(!phpBinaries.isFile()){
89 | phpBinaries = new File(home, "bin/php5/bin/php");
90 | if(!phpBinaries.isFile()){
91 | String pathPhp = exec(Utils.getOS() == WINDOWS ? "where php" : "which php");
92 | if(pathPhp != null){
93 | phpBinaries = new File(pathPhp);
94 | if(!phpBinaries.isFile() || !validatePhpBinaries(phpBinaries)){
95 | showMessageDialog(ChooseServerActivity.this, "Could not autodetect PHP binaries. " +
96 | "Please choose the PHP binaries to run with this server.",
97 | "Binaries not found", WARNING_MESSAGE);
98 | while(true){
99 | JFileChooser binChooser = new JFileChooser(new File(
100 | System.getProperty("os.name").toLowerCase().contains("win") ?
101 | System.getenv("ProgramFiles") : "/Applications"));
102 | binChooser.setFileSelectionMode(FILES_ONLY);
103 | ret = binChooser.showOpenDialog(ChooseServerActivity.this);
104 | if(ret != APPROVE_OPTION){
105 | return;
106 | }
107 | phpBinaries = binChooser.getSelectedFile();
108 | if(validatePhpBinaries(phpBinaries)){
109 | break;
110 | }
111 | showMessageDialog(ChooseServerActivity.this, "Invalid PHP binaries! " +
112 | "Please choose again.", "Invalid binaries", ERROR_MESSAGE);
113 | }
114 | }
115 | }
116 | }
117 | }
118 | ServerMainActivity server = new ServerMainActivity(home, phpBinaries);
119 | initNewActivity(server);
120 | }
121 | }
122 |
123 | private class InstallServerOnClickListener implements ActionListener{
124 | @Override
125 | public void actionPerformed(ActionEvent e){
126 | new InstallServerActivity(ChooseServerActivity.this).init();
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/startup/config/ServerOptionsActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.startup.config;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | import com.github.pemapmodder.pocketminegui.gui.startup.config.adaptor.CheckBoxOptionAdaptor;
21 | import com.github.pemapmodder.pocketminegui.gui.startup.config.adaptor.NumberFieldAdaptor;
22 | import com.github.pemapmodder.pocketminegui.gui.startup.config.adaptor.OptionAdaptor;
23 | import com.github.pemapmodder.pocketminegui.lib.Activity;
24 | import com.github.pemapmodder.pocketminegui.lib.JNumberFilter;
25 | import lombok.Getter;
26 |
27 | import javax.swing.*;
28 | import java.awt.GridLayout;
29 | import java.util.List;
30 | import java.util.Map;
31 |
32 | public abstract class ServerOptionsActivity extends Activity{
33 | @Getter private final Map values;
34 | @Getter private final Map descMap;
35 |
36 | @Getter private JLabel descLabel;
37 | @Getter private JPanel editorPanel;
38 |
39 | @Getter private OptionAdaptor> adaptor;
40 |
41 | private int lastSelected = -1;
42 |
43 | public ServerOptionsActivity(String title, Activity activity, Map map, Map descMap){
44 | super(title, activity);
45 | values = map;
46 | this.descMap = descMap;
47 | }
48 |
49 | @Override
50 | protected void onStart(){
51 | getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
52 | JPanel properties = new JPanel();
53 | descLabel = new JLabel();
54 | editorPanel = new JPanel();
55 | JScrollPane pane = new JScrollPane();
56 | DefaultListModel model = new DefaultListModel<>();
57 | JList list = new JList<>();
58 | list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
59 | list.setSize(list.getWidth(), 300);
60 | list.addListSelectionListener(e -> onSelect(list.getSelectedIndex()));
61 | values.keySet().forEach(model::addElement);
62 | list.setModel(model);
63 | list.revalidate();
64 | list.repaint();
65 | pane.getViewport().add(list);
66 | properties.add(pane);
67 | add(properties);
68 | JPanel detailsPanel = new JPanel(new GridLayout(1, 2));
69 | detailsPanel.add(descLabel);
70 | detailsPanel.add(editorPanel);
71 | add(detailsPanel);
72 | onSelect(0);
73 | setExtendedState(MAXIMIZED_BOTH);
74 | }
75 |
76 | private void onSelect(int index){
77 | if(lastSelected == index){
78 | return;
79 | }
80 | if(lastSelected != -1){
81 | onDeselect(lastSelected);
82 | }
83 | lastSelected = index;
84 | String key = (String) values.keySet().toArray()[index];
85 | descLabel.setText(descMap.get(key));
86 | editorPanel.removeAll();
87 | Object value = values.values().toArray()[index];
88 | if(value instanceof Boolean){
89 | JCheckBox checkBox = new JCheckBox("Enable");
90 | checkBox.setSelected((Boolean) value);
91 | editorPanel.add(checkBox);
92 | adaptor = new CheckBoxOptionAdaptor(checkBox);
93 | }else if(value instanceof Number){
94 | JTextField field = new JTextField();
95 | field.setSize(300, field.getHeight());
96 | field.setDocument(new JNumberFilter().setNegativeAccepted(true));
97 | editorPanel.add(field);
98 | adaptor = new NumberFieldAdaptor(field);
99 | }else if(value instanceof String){
100 | JTextField field = new JTextField();
101 | field.setSize(600, field.getHeight());
102 | editorPanel.add(field);
103 | adaptor = field::getText;
104 | }else if(value instanceof List){
105 | // TODO
106 | adaptor = () -> (List) value;
107 | }else{
108 | adaptor = () -> value;
109 | }
110 | }
111 |
112 | private void onDeselect(int lastSelected){
113 | String key = (String) values.keySet().toArray()[lastSelected];
114 | values.put(key, adaptor.getOption());
115 | }
116 |
117 | @Override
118 | protected void onStop(){
119 | onResult(values);
120 | }
121 |
122 | protected abstract void onResult(Map opts);
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/startup/config/adaptor/CheckBoxOptionAdaptor.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.startup.config.adaptor;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | import lombok.AllArgsConstructor;
21 | import lombok.Getter;
22 |
23 | import javax.swing.JCheckBox;
24 |
25 | @AllArgsConstructor
26 | public class CheckBoxOptionAdaptor implements OptionAdaptor{
27 | @Getter private JCheckBox checkBox;
28 |
29 | @Override
30 | public Boolean getOption(){
31 | return checkBox.isSelected();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/startup/config/adaptor/NumberFieldAdaptor.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.startup.config.adaptor;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | import lombok.AllArgsConstructor;
21 |
22 | import javax.swing.JTextField;
23 |
24 | @AllArgsConstructor
25 | public class NumberFieldAdaptor implements OptionAdaptor{
26 | private JTextField field;
27 |
28 | @Override
29 | public Number getOption(){
30 | String text = field.getText();
31 | double dbl = Double.parseDouble(text);
32 | if(Integer.MIN_VALUE <= dbl && dbl <= Integer.MAX_VALUE){
33 | return (int) dbl;
34 | }
35 | return dbl;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/startup/config/adaptor/OptionAdaptor.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.startup.config.adaptor;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | public interface OptionAdaptor{
21 | public T getOption();
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/startup/installer/FetchVersionsThread.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.startup.installer;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | import com.github.pemapmodder.pocketminegui.gui.startup.installer.cards.ChooseVersionCard;
21 | import lombok.Getter;
22 | import org.apache.commons.io.IOUtils;
23 | import org.json.JSONArray;
24 | import org.json.JSONException;
25 | import org.json.JSONObject;
26 |
27 | import java.io.IOException;
28 | import java.net.MalformedURLException;
29 | import java.net.URL;
30 | import java.text.DateFormat;
31 | import java.text.ParseException;
32 | import java.text.SimpleDateFormat;
33 | import java.util.ArrayList;
34 | import java.util.List;
35 |
36 | public class FetchVersionsThread extends Thread{
37 | @Getter
38 | private final ChooseVersionCard card;
39 | @Getter
40 | private final List releases = new ArrayList<>();
41 | @Getter
42 | private boolean done = false;
43 |
44 | public FetchVersionsThread(ChooseVersionCard card){
45 | this.card = card;
46 | }
47 |
48 | @Override
49 | public void run(){
50 | fetchGitHubReleases();
51 | fetchJenkinsBuilds("http://jenkins.pocketmine.net/job/PocketMine-MP/api/json?depth=1", "dev", ReleaseType.DEVELOPMENT);
52 | fetchJenkinsBuilds("http://jenkins.pocketmine.net/job/PocketMine-MP-Bleeding/api/json?depth=1", "bleeding", ReleaseType.BLEEDING);
53 | fetchPmbBuilds();
54 | done = true;
55 | }
56 |
57 | private void fetchGitHubReleases(){
58 | try{
59 | URL url = new URL("https://api.github.com/repos/PocketMine/PocketMine-MP/releases");
60 | String jsonString = IOUtils.toString(url);
61 | JSONArray releasesArray = new JSONArray(jsonString);
62 | for(Object object : releasesArray){
63 | JSONObject jo = (JSONObject) object;
64 | DateFormat date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
65 | JSONArray assets = jo.getJSONArray("assets");
66 | String pharUrl = null;
67 | for(Object asset : assets){
68 | JSONObject assetObject = (JSONObject) asset;
69 | if(assetObject.getString("name").endsWith(".phar")){
70 | pharUrl = assetObject.getString("browser_download_url");
71 | }
72 | }
73 | if(pharUrl == null){
74 | continue;
75 | }
76 | Release release = new Release(
77 | jo.getString("tag_name"),
78 | jo.getBoolean("prerelease") ? ReleaseType.BETA : ReleaseType.STABLE,
79 | date.parse(jo.getString("published_at")).getTime(),
80 | pharUrl
81 | );
82 | synchronized(releases){
83 | releases.add(release);
84 | }
85 | }
86 | }catch(IOException e){
87 | e.printStackTrace();
88 | }catch(NullPointerException | ClassCastException | JSONException | ParseException e){
89 | System.err.println("GitHub API returned invalid value!");
90 | e.printStackTrace();
91 | }
92 | }
93 |
94 | private void fetchJenkinsBuilds(String urlPath, String buildPrefix, ReleaseType releaseType){
95 | try{
96 | URL url = new URL(urlPath);
97 | String jsonString = IOUtils.toString(url);
98 | JSONObject object = new JSONObject(jsonString);
99 | JSONArray array = object.getJSONArray("builds");
100 | for(Object arrayObject : array){
101 | JSONObject build = (JSONObject) arrayObject;
102 | if(!build.getString("result").equals("SUCCESS")){
103 | continue;
104 | }
105 | String artifactName = null;
106 | for(Object artifactObject : build.getJSONArray("artifacts")){
107 | JSONObject artifact = (JSONObject) artifactObject;
108 | if(artifact.getString("fileName").endsWith(".phar")){
109 | artifactName = artifact.getString("relativePath");
110 | }
111 | }
112 | if(artifactName == null){
113 | continue;
114 | }
115 | Release release = new Release(
116 | buildPrefix + "-" + build.getInt("number"),
117 | releaseType,
118 | build.getLong("timestamp"),
119 | build.getString("url") + "artifact/" + artifactName
120 | );
121 | synchronized(releases){
122 | releases.add(release);
123 | }
124 | }
125 | }catch(MalformedURLException e){
126 | e.printStackTrace();
127 | }catch(IOException | JSONException | NullPointerException | ClassCastException e){
128 | if(e.getMessage().startsWith("Server returned HTTP response code: 521")){
129 | System.err.println("Jenkins server is down!");
130 | return;
131 | }
132 | System.err.println("Jenkins API returned invalid value, resulting in this error: ");
133 | e.printStackTrace();
134 | }
135 | }
136 |
137 | public final static int PMB_TYPE_MASTER = 0;
138 | public final static int PMB_TYPE_BRANCH = 1;
139 | public final static int PMB_TYPE_PR = 2;
140 |
141 | private void fetchPmbBuilds(){
142 | try{
143 | URL url = new URL("http://pmt.mcpe.me/pmb/versions.php");
144 | String source = IOUtils.toString(url);
145 | JSONObject object = new JSONObject(source);
146 | JSONArray versions = object.getJSONArray("versions");
147 | for(Object obj : versions){
148 | JSONObject version = (JSONObject) obj;
149 | String branch = version.getString("branch");
150 | int type = version.getInt("buildType");
151 | String name;
152 | if(type == PMB_TYPE_MASTER){
153 | name = "Latest development build";
154 | }else if(type == PMB_TYPE_BRANCH){
155 | name = "Unstable build for branch " + branch;
156 | }else if(type == PMB_TYPE_PR){
157 | name = "Unverified build for pull request #" + version.getInt("id") + " by @" + version.getString("actor") + ": " + version.getString("title");
158 | }else{
159 | throw new UnsupportedOperationException("Unknown build type " + type);
160 | }
161 | Release release = new Release(name, ReleaseType.PMB, version.getLong("time") * 1000,
162 | "http://pmt.mcpe.me/pmb/dl/" + branch + ".phar");
163 | synchronized(releases){
164 | releases.add(release);
165 | }
166 | }
167 | }catch(IOException | ClassCastException e){
168 | e.printStackTrace();
169 | }
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/startup/installer/InstallPHPThread.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.startup.installer;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | import com.github.pemapmodder.pocketminegui.utils.AsyncTask;
21 | import com.github.pemapmodder.pocketminegui.utils.Utils;
22 | import lombok.Getter;
23 | import lombok.RequiredArgsConstructor;
24 |
25 | import java.io.File;
26 |
27 | @RequiredArgsConstructor
28 | public class InstallPHPThread extends AsyncTask{
29 | private final File home;
30 | @Getter private File result = null;
31 | @Getter private boolean initialized;
32 |
33 | @Override
34 | public void run(){
35 | setMax(100);
36 | setProgress(0);
37 | initialized = true;
38 | Utils.installPHP(home, new Utils.InstallProgressReporter(){
39 | @Override
40 | public void report(double fraction){
41 | setProgress((int) (fraction * 100));
42 | }
43 |
44 | @Override
45 | public void completed(File result){
46 | setProgress(100);
47 | InstallPHPThread.this.result = result;
48 | }
49 |
50 | @Override
51 | public void errored(){
52 | setProgress(100);
53 | }
54 | });
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/startup/installer/InstallServerActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.startup.installer;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 |
21 | import com.github.pemapmodder.pocketminegui.gui.server.ServerMainActivity;
22 | import com.github.pemapmodder.pocketminegui.gui.startup.installer.cards.*;
23 | import com.github.pemapmodder.pocketminegui.lib.Activity;
24 | import com.github.pemapmodder.pocketminegui.lib.card.Card;
25 | import com.github.pemapmodder.pocketminegui.lib.card.CardActivity;
26 | import lombok.Getter;
27 | import lombok.Setter;
28 |
29 | import java.io.File;
30 |
31 | public class InstallServerActivity extends CardActivity{
32 | @Getter private File selectedHome;
33 | @Getter @Setter private File phpBinaries;
34 | @Getter @Setter private Release selectedRelease;
35 |
36 | public InstallServerActivity(Activity parent){
37 | super("Install server", parent);
38 | setExtendedState(MAXIMIZED_BOTH);
39 | }
40 |
41 | @Override
42 | public Card[] getDefaultCards(){
43 | return new Card[]{
44 | new ChooseLocationCard(this),
45 | new ChooseVersionCard(this),
46 | new DownloadProgressCard(this),
47 | new PhpInstallerCard(this),
48 | new ServerSetupCard(this),
49 | };
50 | }
51 |
52 | public void setSelectedHome(File selectedHome){
53 | this.selectedHome = selectedHome;
54 | selectedHome.mkdirs();
55 | }
56 |
57 | @Override
58 | protected void setCard(int index, int exitType){
59 | super.setCard(index, exitType);
60 | setExtendedState(MAXIMIZED_BOTH);
61 | }
62 |
63 | @Override
64 | protected void onFinish(){
65 | super.onFinish();
66 | getParent().initNewActivity(new ServerMainActivity(selectedHome, phpBinaries));
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/github/pemapmodder/pocketminegui/gui/startup/installer/Release.java:
--------------------------------------------------------------------------------
1 | package com.github.pemapmodder.pocketminegui.gui.startup.installer;
2 |
3 | /*
4 | * This file is part of PocketMine-GUI.
5 | *
6 | * PocketMine-GUI is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * PocketMine-GUI is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with PocketMine-GUI. If not, see .
18 | */
19 |
20 | import lombok.AllArgsConstructor;
21 | import lombok.Getter;
22 |
23 | import java.text.SimpleDateFormat;
24 | import java.util.Date;
25 |
26 | @AllArgsConstructor
27 | public class Release{
28 | public final static int LIST_STABLE = 0, LIST_BETA = 1, LIST_DEVELOPMENT = 2, LIST_BLEEDING = 3, LIST_PMB = 4;
29 |
30 | @Getter private String name;
31 | @Getter private ReleaseType type;
32 | @Getter private long publishTime;
33 | @Getter private String pharUrl;
34 |
35 | @Override
36 | public String toString(){
37 | return "" + name + " " + "