Skip to content

Commit d58b461

Browse files
committed
v1.21
1 parent b50845b commit d58b461

File tree

8 files changed

+171
-29
lines changed

8 files changed

+171
-29
lines changed

.idea/inspectionProfiles/profiles_settings.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CHANGELOG.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22
All notable changes to this project will be documented in `CHANGELOG.md`.
33

44
## Added
5-
Nothing has been added.
5+
* A [LanguageHandler][langhand] for handling strings in different languages. If you want to add a new language, read [this][readme-lang]
66

77
## Modified
8-
* A few strings have been changed. I'm going to work on making language files so I can support multiple languages.
8+
Nothing has been modified.
99

1010
## Removed
1111
Nothing has been removed.
1212

1313
## TODOs
14-
- [ ] Optimise IP generation and initial scanning code.[¹][1]
14+
- [ ] Optimise IP generation and initial scanning code.
1515
- [ ] Optimise code in general.
1616
- [ ] Separate tool for viewing servers in DB. (code is already here (`ServerList` class), just need to make it separate)
1717
- [x] ~~Make it save what IP it got to when quitting so that it can resume from that IP on next startup.~~
1818
- [x] ~~Add a GUI for viewing servers in a nice friendly grid.~~
1919

20-
[1]: https://github.com/StupidRepo/MCScanner/blob/main/src/com/stupidrepo/mcscanner/MCScanner.java#L126
20+
[readme-lang]: https://github.com/StupidRepo/MCScanner/tree/main#languages
21+
[langhand]: https://github.com/StupidRepo/MCScanner/blob/main/src/com/stupidrepo/mcscanner/language/LanguageHandler.java

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ Now re-made in Java, and not Python!
2222
3. Build the project with `Build > Build Project`.
2323
4. Run the project with `Run > Run 'MCScanner [run]'`.
2424

25+
## Contributing
26+
### General
27+
If you want to contribute to this project, you can fork this repository, make your changes, and then make a pull request!
28+
### Languages
29+
To contribute to the languages, fork the repository, analyse the `en-GB.json` file, make a new file with your language locale (see [this][lang]), translate the values (not the keys), and then make a pull request!
30+
Please don't use Google Translate :(
31+
2532
## Changelogs
2633
All notable changes to this project will be documented in [`CHANGELOG.md`][changes].
2734

@@ -37,4 +44,6 @@ Oh, and **don't use this program for griefing**. Please.
3744

3845
[changes]: https://github.com/StupidRepo/MCScanner/blob/main/CHANGELOG.md
3946
[latest]: https://github.com/StupidRepo/MCScanner/releases/latest/download/MCScanner.jar
40-
[latest-source]: https://github.com/StupidRepo/MCScanner/archive/refs/heads/main.zip
47+
[latest-source]: https://github.com/StupidRepo/MCScanner/archive/refs/heads/main.zip
48+
49+
[lang]: https://www.oracle.com/java/technologies/javase/jdk17-suported-locales.html

build.gradle

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,21 @@ sourceSets {
1515
java {
1616
srcDirs = ['src']
1717
}
18+
resources {
19+
srcDirs = ["src/main/resources"]
20+
}
1821
}
1922
}
2023

24+
//sourceSets {
25+
// main {
26+
// resources {
27+
// srcDirs "src/main/resources"
28+
// }
29+
// }
30+
//}
31+
32+
2133
mainClassName = 'com.stupidrepo.mcscanner.MCScanner'
2234

2335
jar {

src/com/stupidrepo/mcscanner/DatabaseHandler.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ public class DatabaseHandler {
1717

1818
private final Logger logger = Logger.getLogger("com.stupidrepo.mcscanner");
1919

20+
/**
21+
* Initiates a new DatabaseHandler.
22+
*
23+
* @param uri The URI to the MongoDB Database
24+
*/
2025
public DatabaseHandler(String uri) {
2126
try {
2227
mainMongoClient = MongoClients.create(uri);
@@ -28,6 +33,9 @@ public DatabaseHandler(String uri) {
2833
}
2934
}
3035

36+
/**
37+
* Gets all the servers in the database.
38+
*/
3139
public ArrayList<Document> getServers() {
3240
ArrayList<Document> servers = new ArrayList<>();
3341
try {
@@ -41,6 +49,9 @@ public ArrayList<Document> getServers() {
4149
return servers;
4250
}
4351

52+
/**
53+
* Gets the server count from the database.
54+
*/
4455
public Long getServerCount() {
4556
try {
4657
return mainCollection.countDocuments();
@@ -50,6 +61,14 @@ public Long getServerCount() {
5061
}
5162
}
5263

64+
/**
65+
* Writes an entry to the database.
66+
*
67+
* @param ip The IP of the server (<code>192.168.0.1</code>)
68+
* @param version The version of the server (<code>1.20.1</code>)
69+
* @param motd The MOTD of the server (<code>A Minecraft Server</code>)
70+
* @param maxPlayers The max players of the server (<code>20</code>)
71+
*/
5372
public void writeDetailsToDB(String ip, String version, String motd, int maxPlayers) {
5473
try {
5574
mainCollection
@@ -65,6 +84,14 @@ public void writeDetailsToDB(String ip, String version, String motd, int maxPlay
6584
}
6685
}
6786

87+
/**
88+
* Updates a server in the database.
89+
*
90+
* @param ip The IP of the server
91+
* @param version The version of the server
92+
* @param motd The MOTD of the server
93+
* @param maxPlayers The max players of the server
94+
*/
6895
public void updateServerByIPInDB(String ip, String version, String motd, int maxPlayers) {
6996
try {
7097
mainCollection.updateOne(
@@ -79,6 +106,11 @@ public void updateServerByIPInDB(String ip, String version, String motd, int max
79106
}
80107
}
81108

109+
/**
110+
* Checks if a server is in the database.
111+
*
112+
* @param ip The IP of the server
113+
*/
82114
public boolean isIPInDB(String ip) {
83115
try {
84116
Document myDoc = mainCollection.find(new Document("ip", ip)).first();

src/com/stupidrepo/mcscanner/MCScanner.java

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.stupidrepo.mcscanner;
22

3+
import com.stupidrepo.mcscanner.language.LanguageHandler;
34
import org.bson.Document;
45

56
import javax.swing.*;
@@ -14,6 +15,7 @@
1415
import java.net.Socket;
1516
import java.nio.charset.StandardCharsets;
1617
import java.util.ArrayList;
18+
import java.util.Locale;
1719
import java.util.concurrent.atomic.AtomicInteger;
1820
import java.util.concurrent.atomic.AtomicReference;
1921
import java.util.logging.Level;
@@ -27,20 +29,23 @@ public class MCScanner {
2729
private static int offsetL = 0;
2830
private static boolean stopping = false;
2931

30-
public static void main(String[] var0) {
32+
public static LanguageHandler lang;
33+
34+
public static void main(String[] args) {
3135
AtomicInteger threads = new AtomicInteger(1024);
3236
int timeout = 1000;
33-
int minimumRange = 1;
3437
int maxRange = 255;
3538
int port = 25565;
3639

3740
Logger logger = Logger.getLogger("com.stupidrepo.mcscanner");
3841

39-
float version = 1.20f;
42+
float version = 1.21f;
4043

4144
AtomicReference<String> uri = new AtomicReference<>("mongodb://localhost:27017");
4245

43-
PopupHandler threadsPopup = new PopupHandler("How many threads would you like to use?", "1024", "OK");
46+
lang = new LanguageHandler(Locale.forLanguageTag("en-gb"));
47+
48+
PopupHandler threadsPopup = new PopupHandler(lang.get("question.THREADS"), "1024", "OK");
4449
threadsPopup.showAndWait();
4550

4651
try {
@@ -49,7 +54,7 @@ public static void main(String[] var0) {
4954
logger.log(Level.SEVERE, "Invalid thread count.");
5055
}
5156

52-
PopupHandler mongoDBURIPopup = new PopupHandler("Enter the URI to the MongoDB database:", "mongodb://localhost:27017", "Done");
57+
PopupHandler mongoDBURIPopup = new PopupHandler(lang.get("question.MONGO"), "mongodb://localhost:27017", "Done");
5358
mongoDBURIPopup.showAndWait();
5459

5560
uri.set(mongoDBURIPopup.responseText);
@@ -58,14 +63,14 @@ public static void main(String[] var0) {
5863

5964
logger.log(Level.INFO, "Scanning IPs...");
6065

61-
JFrame frame = new JFrame("MCScanner v" + version);
66+
JFrame frame = new JFrame(lang.get("text.TITLE").formatted(version));
6267
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
6368
frame.setSize(300, 100);
6469
frame.setLayout(new BorderLayout());
6570

6671
ArrayList < Thread > threadList = new ArrayList < Thread > ();
6772

68-
JLabel scannedLabel = new JLabel("Scanned: 0");
73+
JLabel scannedLabel = new JLabel(lang.get("text.SCANNED").formatted(0));
6974
scannedLabel.setHorizontalAlignment(0);
7075

7176
frame.add(scannedLabel, "Center");
@@ -97,16 +102,12 @@ public void windowClosing(java.awt.event.WindowEvent windowEvent) {
97102
}
98103
});
99104

100-
ServerList serverList = new ServerList(databaseHandler);
105+
ServerList serverList = new ServerList(databaseHandler, lang);
101106

102-
JButton viewServersButton = new JButton("Show Server List");
107+
JButton viewServersButton = new JButton(lang.get("button.SERVERLIST"));
103108

104109
viewServersButton.addActionListener(e -> {
105-
if(serverList.toggleGUI()) {
106-
viewServersButton.setText("Hide Server List");
107-
} else {
108-
viewServersButton.setText("Show Server List");
109-
}
110+
serverList.toggleGUI();
110111
});
111112

112113
frame.add(viewServersButton, "North");
@@ -170,7 +171,7 @@ public void windowClosing(java.awt.event.WindowEvent windowEvent) {
170171
try {
171172
nextThread.join();
172173
++scanned;
173-
scannedLabel.setText("Scanned: " + scanned + " (" + ip + ")");
174+
scannedLabel.setText(lang.get("text.SCANNED").formatted(scanned));
174175
} catch (InterruptedException timeout2) {
175176
// Timed out or smth
176177
}
@@ -189,7 +190,7 @@ public void windowClosing(java.awt.event.WindowEvent windowEvent) {
189190
try {
190191
nextThreadAgain.join();
191192
++scanned;
192-
scannedLabel.setText("Scanned: " + scanned);
193+
scannedLabel.setText(lang.get("text.SCANNED").formatted(scanned));
193194
} catch (InterruptedException timeout1) {
194195
// Timeout, again!
195196
}
@@ -287,11 +288,13 @@ public void run() {
287288

288289
class ServerList {
289290
private final DatabaseHandler dbHandler;
291+
private final LanguageHandler lang;
290292
private final JFrame frame;
291293

292-
public ServerList(DatabaseHandler dbHandler) {
294+
public ServerList(DatabaseHandler dbHandler, LanguageHandler lang) {
295+
this.lang = lang;
293296
this.dbHandler = dbHandler;
294-
this.frame = new JFrame("MCScanner - Servers (" + this.dbHandler.getServerCount() + ")");
297+
this.frame = new JFrame(lang.get("text.SERVERLIST.TITLE").formatted(0));
295298
this.frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
296299
this.frame.setSize(720, 500);
297300
this.frame.setLayout(new BorderLayout());
@@ -301,7 +304,7 @@ public ServerList(DatabaseHandler dbHandler) {
301304
new Object[][] {
302305
},
303306
new String[] {
304-
"IP", "MOTD", "Version", "Max Players"
307+
lang.get(this.lang.get("text.SERVERLIST.IP")), this.lang.get("text.SERVERLIST.MOTD"), this.lang.get("text.SERVERLIST.VERSION"), this.lang.get("text.SERVERLIST.MAX_PLAYERS")
305308
}
306309
));
307310
table.getColumnModel().getColumn(0).setPreferredWidth(100);
@@ -328,10 +331,10 @@ public ServerList(DatabaseHandler dbHandler) {
328331
searchBar.addFocusListener(new PlaceholderText("Search", searchBar).getFocusAdapter());
329332

330333
JComboBox<String> searchBy = new JComboBox<String>();
331-
searchBy.addItem("Sort By: IP");
332-
searchBy.addItem("Sort By: MOTD");
333-
searchBy.addItem("Sort By: Version");
334-
searchBy.addItem("Sort By: Max Players");
334+
searchBy.addItem(lang.get("dropdown.SERVERLIST.IP"));
335+
searchBy.addItem(lang.get("dropdown.SERVERLIST.MOTD"));
336+
searchBy.addItem(lang.get("dropdown.SERVERLIST.VERSION"));
337+
searchBy.addItem(lang.get("dropdown.SERVERLIST.MAX_PLAYERS"));
335338
searchBy.setSelectedIndex(2);
336339

337340
searchBar.addActionListener(e -> {
@@ -350,7 +353,7 @@ public ServerList(DatabaseHandler dbHandler) {
350353
Timer timer = new Timer(10000, e -> {
351354
((DefaultTableModel) table.getModel()).setRowCount(0);
352355
ArrayList < Document > documents1 = this.dbHandler.getServers();
353-
this.frame.setTitle("MCScanner - Servers (" + documents1.size() + ")");
356+
this.frame.setTitle(lang.get("text.SERVERLIST.TITLE").formatted(documents1.size()));
354357
for (Document document: documents1) {
355358
String ip = document.getString("ip");
356359
String motd = document.getString("motd");
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.stupidrepo.mcscanner.language;
2+
3+
import org.bson.BsonString;
4+
import org.bson.json.JsonObject;
5+
6+
import java.io.*;
7+
import java.util.*;
8+
import java.util.logging.Logger;
9+
10+
import java.util.logging.Level;
11+
12+
public class LanguageHandler {
13+
private final Hashtable<Object, Object> strings = new Hashtable<>();
14+
15+
private Locale language;
16+
private final Locale fallbackLocale;
17+
18+
private final Logger logger = Logger.getLogger("com.stupidrepo.mcscanner");
19+
20+
public LanguageHandler(Locale fallback) {
21+
this.fallbackLocale = fallback;
22+
this.language = Locale.getDefault();
23+
this.loadStringsToDictionary();
24+
}
25+
26+
public String get(String key) {
27+
if(this.strings.containsKey(key)) {
28+
return ((BsonString) this.strings.get(key)).getValue();
29+
} else {
30+
logger.log(Level.SEVERE, "No string found for key '%s'.".formatted(key));
31+
return key;
32+
}
33+
}
34+
35+
public Locale getLanguage() {
36+
return this.language;
37+
}
38+
39+
public Locale setLanguage(String language) {
40+
this.language = Locale.forLanguageTag(language);
41+
this.loadStringsToDictionary();
42+
return this.language;
43+
}
44+
45+
public void loadStringsToDictionary() {
46+
ClassLoader classLoader = getClass().getClassLoader();
47+
InputStream is = classLoader.getResourceAsStream("lang/%s.json".formatted(this.language.toLanguageTag()));
48+
49+
if (is == null) { is = classLoader.getResourceAsStream("lang/%s.json".formatted(this.fallbackLocale.toLanguageTag())); }
50+
if (is == null) { logger.log(Level.SEVERE, "No language file found for %s or %s!".formatted(this.language.toLanguageTag(), this.fallbackLocale.toLanguageTag())); } else {
51+
try {
52+
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
53+
StringBuilder sb = new StringBuilder();
54+
String line;
55+
while ((line = reader.readLine()) != null) { sb.append(line); }
56+
JsonObject json = new JsonObject(sb.toString());
57+
this.strings.putAll(json.toBsonDocument());
58+
logger.log(Level.INFO, "Loaded language file for %s!".formatted(this.language.toLanguageTag()));
59+
} catch (IOException e) {
60+
e.printStackTrace();
61+
}
62+
}
63+
}
64+
}

src/main/resources/lang/en-GB.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"text.TITLE": "MCScanner v%s",
3+
"text.SCANNED": "Scanned: %s",
4+
5+
"text.SERVERLIST.TITLE": "MCScanner - Servers (%s)",
6+
"text.SERVERLIST.IP": "IP",
7+
"text.SERVERLIST.VERSION": "Version",
8+
"text.SERVERLIST.MOTD": "MOTD",
9+
"text.SERVERLIST.MAX_PLAYERS": "Max Players",
10+
11+
"question.THREADS": "How many threads would you like to use?",
12+
"question.MONGO": "What's the URI to your MongoDB database?",
13+
14+
"button.SERVERLIST": "Toggle Server List",
15+
16+
"dropdown.SERVERLIST.IP": "Sort By: IP",
17+
"dropdown.SERVERLIST.VERSION": "Sort By: Version",
18+
"dropdown.SERVERLIST.MOTD": "Sort By: MOTD",
19+
"dropdown.SERVERLIST.MAX_PLAYERS": "Sort By: Max Players"
20+
}

0 commit comments

Comments
 (0)