From 5c43347710aff474597f872801ed7e89fba4d208 Mon Sep 17 00:00:00 2001 From: jeffcheasey88 Date: Sun, 26 Jan 2025 15:14:10 +0100 Subject: [PATCH] SEE for groups messages --- PeerAtCodeFramework.jar | Bin 545946 -> 545917 bytes src/dev/peerat/backend/Configuration.java | 6 ++ src/dev/peerat/backend/Main.java | 23 +++++- src/dev/peerat/backend/routes/EventSSE.java | 75 ++++++++++++++++++ .../routes/admins/GroupController.java | 31 ++++++++ 5 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 src/dev/peerat/backend/routes/EventSSE.java create mode 100644 src/dev/peerat/backend/routes/admins/GroupController.java diff --git a/PeerAtCodeFramework.jar b/PeerAtCodeFramework.jar index d48268bf179ffd2ad4e21ec431be34097ff4de91..13a01aea16b262eba3a1153d700593cd3f8a88ac 100644 GIT binary patch delta 24464 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 X@CQ4K1Ad>cqlj^&Hg8NB9rphNm0F+V delta 24827 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 locker = router.getExceptionLogger(); + + locker.init(key); + try { + while(true){ + locker.lock(key); + locker.getValue(key).printStackTrace(); + } + }catch(Exception e){ + e.printStackTrace(); + } + locker.remove(key); + } + }).start(); + if(config.useSsl()) router.configureSSL(config.getSslKeystore(), config.getSslKeystorePasswd()); router.listen(config.getTcpPort(), config.useSsl()); } @@ -150,7 +168,8 @@ public class Main{ .of(repo, router, config, new RouteExtracter(router), config.getMail()) .of("waitting", new HashMap<>()) .of("leaderboard", new Locker<>()) - .of("groups", new Locker<>())); + .of("groups", new Locker<>()) + .of("groupMessages", new Locker<>())); // Bot bot = new Bot(config, repo, groupLock); // bot.start(); diff --git a/src/dev/peerat/backend/routes/EventSSE.java b/src/dev/peerat/backend/routes/EventSSE.java new file mode 100644 index 0000000..1568277 --- /dev/null +++ b/src/dev/peerat/backend/routes/EventSSE.java @@ -0,0 +1,75 @@ +package dev.peerat.backend.routes; + +import java.util.regex.Matcher; + +import dev.peerat.backend.Configuration; +import dev.peerat.backend.model.Group; +import dev.peerat.backend.model.PeerAtUser; +import dev.peerat.backend.repository.DatabaseGroupRepository; +import dev.peerat.backend.repository.DatabaseRepository; +import dev.peerat.framework.Context; +import dev.peerat.framework.HttpWriter; +import dev.peerat.framework.Injection; +import dev.peerat.framework.Locker; +import dev.peerat.framework.Locker.Key; +import dev.peerat.framework.Route; + +public class EventSSE{ + + private Locker locker; + private DatabaseGroupRepository repo; + private int eventChapter; + + public EventSSE(@Injection("groupMessages") Locker locker, DatabaseRepository repo, Configuration config){ + this.locker = locker; + this.repo = repo.getGroupRepository(); + this.eventChapter = config.getEventChapter(); + } + + @Route(path = "^/group/event/$", needLogin = true) + public void connect(Context context, HttpWriter writer) throws Exception { + Group group = repo.getPlayerGroup(context.getUser().getId(), this.eventChapter); + if(group == null){ + context.response(401); + return; + } + context.response(200, "Content-Type: text/event-stream"); + + Key key = new Key(); + + locker.init(key); + try { + while(true){ + GroupMessage message = locker.getValue(key); + if(message.getGroup() == null || message.getGroup().equals(group.getName())){ + writer.write("data: "+message.getMessage()+"\n\n"); + writer.flush(); + } + locker.lock(key); + } + }catch(Exception e){ + e.printStackTrace(); + } + locker.remove(key); + } + + public static class GroupMessage{ + + private String group; + private String message; + + public GroupMessage(String group, String message){ + this.group = group; + this.message = message; + } + + public String getGroup(){ + return this.group; + } + + public String getMessage(){ + return this.message; + } + + } +} diff --git a/src/dev/peerat/backend/routes/admins/GroupController.java b/src/dev/peerat/backend/routes/admins/GroupController.java new file mode 100644 index 0000000..5f024fa --- /dev/null +++ b/src/dev/peerat/backend/routes/admins/GroupController.java @@ -0,0 +1,31 @@ +package dev.peerat.backend.routes.admins; + +import dev.peerat.backend.routes.EventSSE.GroupMessage; +import dev.peerat.framework.Context; +import dev.peerat.framework.HttpReader; +import dev.peerat.framework.Injection; +import dev.peerat.framework.Locker; +import dev.peerat.framework.Route; +import dev.peerat.framework.utils.json.JsonMap; + +public class GroupController { + + private Locker locker; + + public GroupController(@Injection("groupMessages") Locker locker){ + this.locker = locker; + } + + @Route(path = "^/admin/event/$", needLogin = true) + public void send(Context context, HttpReader reader) throws Exception{ + JsonMap json = reader.readJson(); + if(!json.has("message")){ + context.response(400); + return; + } + + locker.setValue(new GroupMessage(json.get("group"), json.get("message"))); + context.response(200); + } + +}