From 4d057ca562ebf75551c280dc137f7abf99a08692 Mon Sep 17 00:00:00 2001 From: brulijam Date: Tue, 25 Jun 2024 18:16:06 +0200 Subject: [PATCH] did a lot of stuff --- .gitignore | 0 README.md | 0 pom.xml | 23 ++++ .../minecraftapi/MinecraftapiApplication.java | 1 - .../controller/MinecraftController.java | 112 +++++++++++++++ .../controller/TelegramBotController.java | 27 ++++ .../controller/TutelController.java | 47 +++++++ .../brulijam/minecraftapi/model/Tutel.java | 41 ++++++ .../minecraftapi/service/MinecraftQuery.java | 127 ++++++++++++++++++ .../minecraftapi/service/TelegramService.java | 42 ++++++ .../minecraftapi/service/TutelService.java | 43 ++++++ .../minecraftapi/telegrambot/TelegramBot.java | 82 +++++++++++ .../telegrambot/TelegramBotInitializer.java | 27 ++++ .../MinecraftapiApplicationTests.java | 0 14 files changed, 571 insertions(+), 1 deletion(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 README.md mode change 100644 => 100755 pom.xml mode change 100644 => 100755 src/main/java/com/brulijam/minecraftapi/MinecraftapiApplication.java create mode 100755 src/main/java/com/brulijam/minecraftapi/controller/MinecraftController.java create mode 100644 src/main/java/com/brulijam/minecraftapi/controller/TelegramBotController.java create mode 100755 src/main/java/com/brulijam/minecraftapi/controller/TutelController.java create mode 100755 src/main/java/com/brulijam/minecraftapi/model/Tutel.java create mode 100755 src/main/java/com/brulijam/minecraftapi/service/MinecraftQuery.java create mode 100644 src/main/java/com/brulijam/minecraftapi/service/TelegramService.java create mode 100644 src/main/java/com/brulijam/minecraftapi/service/TutelService.java create mode 100644 src/main/java/com/brulijam/minecraftapi/telegrambot/TelegramBot.java create mode 100644 src/main/java/com/brulijam/minecraftapi/telegrambot/TelegramBotInitializer.java mode change 100644 => 100755 src/test/java/com/brulijam/minecraftapi/MinecraftapiApplicationTests.java diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/pom.xml b/pom.xml old mode 100644 new mode 100755 index 7609cad..a02ffc8 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,29 @@ spring-boot-starter-test test + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.5.0 + + + + org.json + json + 20231013 + + + com.google.code.gson + gson + 2.8.9 + + + + org.telegram + telegrambots + 6.9.7.1 + diff --git a/src/main/java/com/brulijam/minecraftapi/MinecraftapiApplication.java b/src/main/java/com/brulijam/minecraftapi/MinecraftapiApplication.java old mode 100644 new mode 100755 index d9ac2e7..0f2491b --- a/src/main/java/com/brulijam/minecraftapi/MinecraftapiApplication.java +++ b/src/main/java/com/brulijam/minecraftapi/MinecraftapiApplication.java @@ -5,7 +5,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class MinecraftapiApplication { - public static void main(String[] args) { SpringApplication.run(MinecraftapiApplication.class, args); } diff --git a/src/main/java/com/brulijam/minecraftapi/controller/MinecraftController.java b/src/main/java/com/brulijam/minecraftapi/controller/MinecraftController.java new file mode 100755 index 0000000..81a1444 --- /dev/null +++ b/src/main/java/com/brulijam/minecraftapi/controller/MinecraftController.java @@ -0,0 +1,112 @@ +package com.brulijam.minecraftapi.controller; + +import com.brulijam.minecraftapi.service.MinecraftQuery; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.json.JSONObject; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.net.InetSocketAddress; + +@RestController +@Tag(name = "Minecraft Server API") +public class MinecraftController { + +// @Operation(summary = "example summary", description = "example description") +// @GetMapping("/getMeem") +// public String getMeem() { +// return "Snens"; +// } +// +// @PostMapping("/postMeem") +// public String postMeem(@Parameter(name = "name", description = "name of stuff", example = "srgjbngeir") @RequestParam String name) { +// return name + "meem"; +// } + + @GetMapping(value = "/getAll", produces = "application/json") + public String all(@Parameter(name = "host", description = "host of minecraft server", example = "134.255.208.230") String host, @Parameter(name = "port", description = "Server Port", example = "57200") int port) throws IOException { + MinecraftQuery query = new MinecraftQuery(); + query.setHost(new InetSocketAddress(host, port)); + return query.fetchData(); + } + + @GetMapping(value = "/getGameVersion", produces = "application/json") + public String getGameVersion(@Parameter(name = "host", description = "host of minecraft server", example = "134.255.208.230") String host, @Parameter(name = "port", description = "Server Port", example = "57200") int port) throws IOException { + MinecraftQuery query = new MinecraftQuery(); + query.setHost(new InetSocketAddress(host, port)); + String data = query.fetchData(); + JSONObject json = new JSONObject(data); + + return json.getJSONObject("version").toString(); + } + + @GetMapping(value = "/getPlayers", produces = "application/json") + public String getPlayers(@Parameter(name = "host", description = "host of minecraft server", example = "134.255.208.230") String host, @Parameter(name = "port", description = "Server Port", example = "57200") int port) throws IOException { + MinecraftQuery query = new MinecraftQuery(); + query.setHost(new InetSocketAddress(host, port)); + String data = query.fetchData(); + JSONObject json = new JSONObject(data); + + return json.getJSONObject("players").toString(); + } + + @GetMapping(value = "/getOnlinePlayers", produces = "application/json") + public String getOnlinePlayers(@Parameter(name = "host", description = "host of minecraft server", example = "134.255.208.230") String host, @Parameter(name = "port", description = "Server Port", example = "57200") int port) throws IOException { + MinecraftQuery query = new MinecraftQuery(); + query.setHost(new InetSocketAddress(host, port)); + String data = query.fetchData(); + JSONObject json = new JSONObject(data); + + String onlinePlayers; + try { + onlinePlayers = json.getJSONObject("players").getJSONArray("sample").toString(); + } catch(Exception e) { + onlinePlayers = "no players online"; + } + + + return onlinePlayers; + } + + + @GetMapping(value = "/getFavicon", produces = "application/json") + public String getFavicon(@Parameter(name = "host", description = "host of minecraft server", example = "134.255.208.230") String host, @Parameter(name = "port", description = "Server Port", example = "57200") int port) throws IOException { + MinecraftQuery query = new MinecraftQuery(); + query.setHost(new InetSocketAddress(host, port)); + String data = query.fetchData(); + JSONObject json = new JSONObject(data); + + String favicon = json.getString("favicon"); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("favicon", favicon); + + return jsonObject.toString(); + } + + @GetMapping(value = "/getDescription", produces = "application/json") + public String getDescription(@Parameter(name = "host", description = "host of minecraft server", example = "134.255.208.230") String host, @Parameter(name = "port", description = "Server Port", example = "57200") int port) throws IOException { + MinecraftQuery query = new MinecraftQuery(); + query.setHost(new InetSocketAddress(host, port)); + String data = query.fetchData(); + JSONObject json = new JSONObject(data); + + return json.getJSONObject("description").toString(); + } + + + + +// @GetMapping(value = "/{host}/all", produces = "application/json") +// public String ipAll(@Parameter(name = "host", description = "host of minecraft server", example = "5.75.236.165") @PathVariable String host, @Parameter(name = "port", description = "Server Port", example = "25565") int port) throws IOException { +// return (ServerListPinger.queryServer(host, port)); +// } + +// @GetMapping("/products/{id}") +// public ResponseEntity getProduct(@PathVariable("id") @Parameter(name = "id", description = "Product id", example = "1") Long id) { +// //retrieval logic +// return ResponseEntity.ok(new Product(1, "Product 1", "$21.99")); +// } + +} diff --git a/src/main/java/com/brulijam/minecraftapi/controller/TelegramBotController.java b/src/main/java/com/brulijam/minecraftapi/controller/TelegramBotController.java new file mode 100644 index 0000000..9f048a6 --- /dev/null +++ b/src/main/java/com/brulijam/minecraftapi/controller/TelegramBotController.java @@ -0,0 +1,27 @@ +package com.brulijam.minecraftapi.controller; + +import com.brulijam.minecraftapi.telegrambot.TelegramBot; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +@Slf4j +@RestController +@RequestMapping("/telegramBot") +@Tag(name= "TelegramBot Controller") +@RequiredArgsConstructor +public class TelegramBotController { + + private final TelegramBot telegramBot; + + @Operation(summary = "sends a message") + @PostMapping(value = "/sendMessage/{userId}", produces = "application/json") + public void sendMessage(@PathVariable(name = "userId") long userId, + @Parameter(name = "message", description = "message to send", example = "Some Message :)") @RequestBody String message) { + log.info("{}", userId); + telegramBot.sendMessage(userId, message); + } +} diff --git a/src/main/java/com/brulijam/minecraftapi/controller/TutelController.java b/src/main/java/com/brulijam/minecraftapi/controller/TutelController.java new file mode 100755 index 0000000..7e06df5 --- /dev/null +++ b/src/main/java/com/brulijam/minecraftapi/controller/TutelController.java @@ -0,0 +1,47 @@ +package com.brulijam.minecraftapi.controller; + +import com.brulijam.minecraftapi.model.Tutel; +import com.brulijam.minecraftapi.service.TutelService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/tutel") +@Tag(name= "Tutel Controller") +@RequiredArgsConstructor +public class TutelController { + + private final TutelService tutelService; + + @GetMapping(value = "/getAll", produces = "application/json") + public List getAll() { + return tutelService.getTutelList(); + } + + @GetMapping(value = "/getByLabel", produces = "application/json") + public Tutel getTutelByLabel(@Parameter(name = "label", description = "label of the turtle", example = "Turtle-1234") String label) { + return tutelService.getByLabel(label); + } + + @Operation(summary = "adds a tutel") + @PostMapping(value = "/add") + public Tutel addTutel(@Parameter(name = "label", description = "label of the tutel") @RequestParam String label, + @Parameter(name = "telegramUserId", description = "Telegram ID of the user the Turtle belongs to") @RequestParam String telegramUserId) { + Tutel tutel = new Tutel(label, telegramUserId); + tutelService.addToList(tutel); + return tutel; + } + + @Operation(summary = "removes a tutel") + @DeleteMapping(value = "/remove") + public void removeTutel(@Parameter(name = "id", description = "id of the tutel") @RequestBody long id) { + tutelService.removeById(id); + } + + +} diff --git a/src/main/java/com/brulijam/minecraftapi/model/Tutel.java b/src/main/java/com/brulijam/minecraftapi/model/Tutel.java new file mode 100755 index 0000000..b914069 --- /dev/null +++ b/src/main/java/com/brulijam/minecraftapi/model/Tutel.java @@ -0,0 +1,41 @@ +package com.brulijam.minecraftapi.model; + +import com.brulijam.minecraftapi.service.TutelService; +import lombok.Data; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +//@Getter +//@Setter +//@AllArgsConstructor +@Data +@RequiredArgsConstructor +public class Tutel { + + private final long id; + private final String telegramUserId; + private final String label; + private int fuelLevel; + private JSONObject inventory; + + + public Tutel(String label, String telegramUserId) { + if (label.endsWith("=")) { + label = label.substring(0, label.length() - 1); + } + label = label.replace("+", " "); + this.label = label; + this.id = Math.abs(this.hashCode()); + this.telegramUserId = telegramUserId; + } + + + + +} diff --git a/src/main/java/com/brulijam/minecraftapi/service/MinecraftQuery.java b/src/main/java/com/brulijam/minecraftapi/service/MinecraftQuery.java new file mode 100755 index 0000000..b790b06 --- /dev/null +++ b/src/main/java/com/brulijam/minecraftapi/service/MinecraftQuery.java @@ -0,0 +1,127 @@ +package com.brulijam.minecraftapi.service; + +import com.google.gson.Gson; +import lombok.Getter; +import lombok.Setter; + +import java.io.*; +import java.net.InetSocketAddress; +import java.net.Socket; + +@Setter +@Getter +public class MinecraftQuery { + + private InetSocketAddress host; + private final Gson gson = new Gson(); + + public int readVarInt(DataInputStream in) throws IOException { + int i = 0; + int j = 0; + while (true) { + int k = in.readByte(); + i |= (k & 0x7F) << j++ * 7; + if (j > 5) throw new RuntimeException("VarInt too big"); + if ((k & 0x80) != 128) break; + } + return i; + } + + public void writeVarInt(DataOutputStream out, int paramInt) throws IOException { + while (true) { + if ((paramInt & 0xFFFFFF80) == 0) { + out.writeByte(paramInt); + return; + } + + out.writeByte(paramInt & 0x7F | 0x80); + paramInt >>>= 7; + } + } + + public String fetchData() throws IOException { + + Socket socket = new Socket(); + OutputStream outputStream; + DataOutputStream dataOutputStream; + InputStream inputStream; + InputStreamReader inputStreamReader; + + int timeout = 7000; + socket.setSoTimeout(timeout); + + socket.connect(host, timeout); + + outputStream = socket.getOutputStream(); + dataOutputStream = new DataOutputStream(outputStream); + + inputStream = socket.getInputStream(); + inputStreamReader = new InputStreamReader(inputStream); + + ByteArrayOutputStream b = new ByteArrayOutputStream(); + DataOutputStream handshake = new DataOutputStream(b); + handshake.writeByte(0x00); //packet id for handshake + writeVarInt(handshake, 4); //protocol version + writeVarInt(handshake, this.host.getHostString().length()); //host length + handshake.writeBytes(this.host.getHostString()); //host string + handshake.writeShort(host.getPort()); //port + writeVarInt(handshake, 1); //state (1 for handshake) + + writeVarInt(dataOutputStream, b.size()); //prepend size + dataOutputStream.write(b.toByteArray()); //write handshake packet + + + dataOutputStream.writeByte(0x01); //size is only 1 + dataOutputStream.writeByte(0x00); //packet id for ping + DataInputStream dataInputStream = new DataInputStream(inputStream); + int size = readVarInt(dataInputStream); //size of packet + int id = readVarInt(dataInputStream); //packet id + +// if (id == -1) { +// throw new IOException("Premature end of stream."); +// } +// +// if (id != 0x00) { //we want a status response +// throw new IOException("Invalid packetID"); +// } + int length = readVarInt(dataInputStream); //length of json string + +// if (length == -1) { +// throw new IOException("Premature end of stream."); +// } +// +// if (length == 0) { +// throw new IOException("Invalid string length."); +// } + + byte[] in = new byte[length]; + dataInputStream.readFully(in); //read json string + String json = new String(in); + + + long now = System.currentTimeMillis(); + dataOutputStream.writeByte(0x09); //size of packet + dataOutputStream.writeByte(0x01); //0x01 for ping + dataOutputStream.writeLong(now); //time!? + + readVarInt(dataInputStream); + id = readVarInt(dataInputStream); +// if (id == -1) { +// throw new IOException("Premature end of stream."); +// } +// +// if (id != 0x01) { +// throw new IOException("Invalid packetID"); +// } + + System.out.println(json); + + dataOutputStream.close(); + outputStream.close(); + inputStreamReader.close(); + inputStream.close(); + socket.close(); + + return json; + } +} diff --git a/src/main/java/com/brulijam/minecraftapi/service/TelegramService.java b/src/main/java/com/brulijam/minecraftapi/service/TelegramService.java new file mode 100644 index 0000000..0658d2b --- /dev/null +++ b/src/main/java/com/brulijam/minecraftapi/service/TelegramService.java @@ -0,0 +1,42 @@ +package com.brulijam.minecraftapi.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.telegram.telegrambots.meta.api.objects.User; + +import java.util.*; + +@Component +@RequiredArgsConstructor +public class TelegramService { + + private final List telegramUsers = new ArrayList<>(); + // Maps userId to token + private final Map tokens = new HashMap<>(); + + public void addUserToList(User user) { + telegramUsers.add(user); + + String randomUUID = UUID.randomUUID().toString().replaceAll("_", ""); + tokens.put(user.getId(), randomUUID); + + } + + public User getUserByUserId(long userId) { + return telegramUsers.stream() + .filter(user -> user.getId() == userId) + .findFirst() + .orElse(null); + } + + public User getUserByUsername(String username) { + return telegramUsers.stream() + .filter(User -> User.getUserName().equals(username)) + .findFirst() + .orElse(null); + } + + public String getTokenByUserId(long userId) { + return tokens.get(userId); + } +} diff --git a/src/main/java/com/brulijam/minecraftapi/service/TutelService.java b/src/main/java/com/brulijam/minecraftapi/service/TutelService.java new file mode 100644 index 0000000..beb90b3 --- /dev/null +++ b/src/main/java/com/brulijam/minecraftapi/service/TutelService.java @@ -0,0 +1,43 @@ +package com.brulijam.minecraftapi.service; + +import com.brulijam.minecraftapi.model.Tutel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@RequiredArgsConstructor +@Component +public class TutelService { + + private final List tutelList = new ArrayList<>(); + + public void addToList(Tutel tutel) { + tutelList.add(tutel); + } + + public void removeById(long id) { + Tutel tutel = tutelList.stream() + .filter(turtle -> turtle.getId() == id) + .findFirst() + .orElse(null); + tutelList.remove(tutel); + } + + public Tutel getById(long id) { + return tutelList.stream() + .filter(tutel -> tutel.getId() == id) + .findFirst() + .orElse(null); + } + + public Tutel getByLabel(String label) { + return tutelList.stream() + .filter(tutel -> tutel.getLabel().equals(label)) + .findFirst() + .orElse(null); + } +} diff --git a/src/main/java/com/brulijam/minecraftapi/telegrambot/TelegramBot.java b/src/main/java/com/brulijam/minecraftapi/telegrambot/TelegramBot.java new file mode 100644 index 0000000..64031e4 --- /dev/null +++ b/src/main/java/com/brulijam/minecraftapi/telegrambot/TelegramBot.java @@ -0,0 +1,82 @@ +package com.brulijam.minecraftapi.telegrambot; + +import com.brulijam.minecraftapi.service.TelegramService; +import com.brulijam.minecraftapi.service.TutelService; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.telegram.telegrambots.bots.TelegramLongPollingBot; +import org.telegram.telegrambots.meta.api.methods.send.SendMessage; +import org.telegram.telegrambots.meta.api.objects.Update; +import org.telegram.telegrambots.meta.api.objects.User; +import org.telegram.telegrambots.meta.exceptions.TelegramApiException; + +@Component +@RequiredArgsConstructor +@Getter +public class TelegramBot extends TelegramLongPollingBot { + + private final TutelService tutelService; + private final TelegramService telegramService; + + @Value("${bot.name}") + private String botUsername; + @Value("${bot.token}") + private String botToken; + + @Override + public void onUpdateReceived(Update update) { + + if (update.hasMessage() && update.getMessage().hasText()) { + User fromUser = update.getMessage().getFrom(); + + String receivedMessage = update.getMessage().getText(); + + handeleMessage(fromUser, receivedMessage); + + + } + } + + private void handeleMessage(User fromUser, String receivedMessage) { + Long userId = fromUser.getId(); + + if (receivedMessage.equals("/start")) { + sendMessage(userId, "Your Telegram userId is " + userId); + } else if (receivedMessage.equals("/list_tutels")) { + if (userId == 5334468232L) { + sendMessage(userId, "user is Brulijam"); + // send all tutels + sendMessage(userId, tutelService.getTutelList().toString()); + } else { + sendMessage(userId, "who are you?"); + } + } else { + sendMessage(userId, "huh?"); + } + } + + @Override + public String getBotUsername() { + return botUsername; + } + + @Override + public String getBotToken() { + return botToken; + } + + public void sendMessage(Long chatId, String messageToSend) { + SendMessage sendMessage = SendMessage.builder() + .chatId(chatId.toString()) + .text(messageToSend) + .build(); + + try { + execute(sendMessage); + } catch (TelegramApiException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/brulijam/minecraftapi/telegrambot/TelegramBotInitializer.java b/src/main/java/com/brulijam/minecraftapi/telegrambot/TelegramBotInitializer.java new file mode 100644 index 0000000..53b3aa3 --- /dev/null +++ b/src/main/java/com/brulijam/minecraftapi/telegrambot/TelegramBotInitializer.java @@ -0,0 +1,27 @@ +package com.brulijam.minecraftapi.telegrambot; + +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; +import org.telegram.telegrambots.meta.TelegramBotsApi; +import org.telegram.telegrambots.meta.exceptions.TelegramApiException; +import org.telegram.telegrambots.updatesreceivers.DefaultBotSession; + +@Component +public class TelegramBotInitializer { + private final TelegramBot telegramBot; + + public TelegramBotInitializer(TelegramBot telegramBot) { + this.telegramBot = telegramBot; + } + + @EventListener({ContextRefreshedEvent.class}) + public void initialize() { + try { + TelegramBotsApi telegramBotsApi = new TelegramBotsApi(DefaultBotSession.class); + telegramBotsApi.registerBot(telegramBot); + } catch (TelegramApiException e) { + e.printStackTrace(); + } + } +} diff --git a/src/test/java/com/brulijam/minecraftapi/MinecraftapiApplicationTests.java b/src/test/java/com/brulijam/minecraftapi/MinecraftapiApplicationTests.java old mode 100644 new mode 100755