Skip to content
This repository was archived by the owner on Apr 7, 2019. It is now read-only.

Commit 4a32b7a

Browse files
working ws connection & player updates
1 parent 04483fa commit 4a32b7a

File tree

9 files changed

+275
-29
lines changed

9 files changed

+275
-29
lines changed

src/main/java/io/rudin/minetest/tileserver/TileServer.java

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
package io.rudin.minetest.tileserver;
22

3-
import static spark.Spark.get;
4-
import static spark.Spark.init;
5-
import static spark.Spark.port;
6-
import static spark.Spark.staticFileLocation;
7-
import static spark.Spark.stop;
8-
93
import java.util.concurrent.ScheduledExecutorService;
104
import java.util.concurrent.TimeUnit;
115
import java.util.concurrent.atomic.AtomicBoolean;
@@ -15,43 +9,52 @@
159

1610
import io.rudin.minetest.tileserver.config.TileServerConfig;
1711
import io.rudin.minetest.tileserver.job.UpdateChangedTilesJob;
12+
import io.rudin.minetest.tileserver.job.UpdatePlayerJob;
1813
import io.rudin.minetest.tileserver.module.ConfigModule;
1914
import io.rudin.minetest.tileserver.module.DBModule;
2015
import io.rudin.minetest.tileserver.module.ServiceModule;
2116
import io.rudin.minetest.tileserver.route.PlayerRoute;
2217
import io.rudin.minetest.tileserver.route.TileRoute;
2318
import io.rudin.minetest.tileserver.transformer.JsonTransformer;
19+
import io.rudin.minetest.tileserver.ws.WebSocketHandler;
20+
import io.rudin.minetest.tileserver.ws.WebSocketUpdater;
21+
22+
import static spark.Spark.*;
2423

2524
public class TileServer {
2625

27-
private static Injector injector;
26+
private static Injector injector = Guice.createInjector(
27+
new ConfigModule(),
28+
new DBModule(),
29+
new ServiceModule()
30+
);
2831

2932
public static void main(String[] args) throws Exception {
30-
31-
Injector injector = Guice.createInjector(
32-
new ConfigModule(),
33-
new DBModule(),
34-
new ServiceModule()
35-
);
36-
33+
3734
TileServerConfig cfg = injector.getInstance(TileServerConfig.class);
3835

3936
DBMigration dbMigration = injector.getInstance(DBMigration.class);
4037
dbMigration.migrate();
4138

4239
staticFileLocation("/public");
4340
port(cfg.httPort());
44-
init();
45-
41+
4642
JsonTransformer json = injector.getInstance(JsonTransformer.class);
47-
43+
44+
webSocket("/ws", WebSocketHandler.class);
4845
get("/tiles/:z/:x/:y", injector.getInstance(TileRoute.class));
4946
get("/player", injector.getInstance(PlayerRoute.class), json);
50-
47+
48+
//Initialize web server
49+
init();
50+
51+
//Initialize ws updater
52+
injector.getInstance(WebSocketUpdater.class).init();
53+
5154
ScheduledExecutorService executor = injector.getInstance(ScheduledExecutorService.class);
52-
UpdateChangedTilesJob tilesJob = injector.getInstance(UpdateChangedTilesJob.class);
53-
54-
executor.scheduleAtFixedRate(tilesJob, 0, 2, TimeUnit.SECONDS);
55+
56+
executor.scheduleAtFixedRate(injector.getInstance(UpdateChangedTilesJob.class), 0, 2, TimeUnit.SECONDS);
57+
executor.scheduleAtFixedRate(injector.getInstance(UpdatePlayerJob.class), 0, 1, TimeUnit.SECONDS);
5558

5659
AtomicBoolean running = new AtomicBoolean(true);
5760

src/main/java/io/rudin/minetest/tileserver/job/UpdateChangedTilesJob.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import javax.inject.Inject;
66
import javax.inject.Singleton;
77

8+
import io.rudin.minetest.tileserver.service.EventBus;
89
import org.jooq.Cursor;
910
import org.jooq.DSLContext;
1011
import org.jooq.Record2;
@@ -17,11 +18,14 @@
1718
public class UpdateChangedTilesJob implements Runnable {
1819

1920
@Inject
20-
public UpdateChangedTilesJob(DSLContext ctx, TileCache tileCache) {
21+
public UpdateChangedTilesJob(DSLContext ctx, TileCache tileCache, EventBus eventBus) {
2122
this.ctx = ctx;
2223
this.tileCache = tileCache;
24+
this.eventBus = eventBus;
2325
}
2426

27+
private final EventBus eventBus;
28+
2529
private final DSLContext ctx;
2630

2731
private final TileCache tileCache;
@@ -52,19 +56,25 @@ public void run() {
5256
Integer x = change.get(TILESERVER_BLOCK_CHANGES.POSX);
5357
Integer z = change.get(TILESERVER_BLOCK_CHANGES.POSZ);
5458

55-
System.out.println("Mapblock changed: " + x + "/" + z + " (Coordinates: " + x*16 + "/" + z*16 + ")");
5659

5760
TileInfo tileInfo = CoordinateResolver.fromCoordinatesMinZoom(x, z);
5861

5962
//remove all tiles in every zoom
6063
for (int i=CoordinateResolver.MAX_ZOOM; i>=CoordinateResolver.MIN_ZOOM; i--) {
6164
TileInfo zoomedTile = tileInfo.toZoom(i);
62-
65+
66+
EventBus.TileChangedEvent event = new EventBus.TileChangedEvent();
67+
event.x = zoomedTile.x;
68+
event.y = zoomedTile.y;
69+
event.zoom = zoomedTile.zoom;
70+
event.mapblockX = x;
71+
event.mapblockZ = z;
72+
eventBus.post(event);
73+
6374
tileCache.remove(zoomedTile.x, zoomedTile.y, zoomedTile.zoom);
6475
}
65-
66-
//TODO: event-bus for ui notification
67-
76+
77+
//TODO: atomic change
6878
ctx
6979
.update(TILESERVER_BLOCK_CHANGES)
7080
.set(TILESERVER_BLOCK_CHANGES.CHANGED, false)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package io.rudin.minetest.tileserver.job;
2+
3+
import io.rudin.minetest.tileserver.blockdb.tables.pojos.Player;
4+
import io.rudin.minetest.tileserver.service.EventBus;
5+
import org.jooq.DSLContext;
6+
7+
import javax.inject.Inject;
8+
import javax.inject.Singleton;
9+
10+
import java.sql.Timestamp;
11+
import java.util.List;
12+
13+
import static io.rudin.minetest.tileserver.blockdb.tables.Player.PLAYER;
14+
15+
@Singleton
16+
public class UpdatePlayerJob implements Runnable {
17+
18+
@Inject
19+
public UpdatePlayerJob(DSLContext ctx, EventBus eventBus){
20+
this.ctx = ctx;
21+
this.eventBus = eventBus;
22+
}
23+
24+
private final DSLContext ctx;
25+
26+
private final EventBus eventBus;
27+
28+
private Timestamp timestamp = new Timestamp(0L);
29+
30+
private boolean running = false;
31+
32+
@Override
33+
public void run() {
34+
if (running)
35+
return;
36+
37+
try {
38+
running = true;
39+
40+
List<Player> players = ctx
41+
.selectFrom(PLAYER)
42+
.where(PLAYER.MODIFICATION_DATE.gt(timestamp))
43+
.fetch()
44+
.into(Player.class);
45+
46+
for (Player player : players) {
47+
48+
Timestamp modificationDate = player.getModificationDate();
49+
50+
if (modificationDate.after(timestamp)) {
51+
//Rember newest modification date
52+
this.timestamp = modificationDate;
53+
}
54+
55+
EventBus.PlayerMovedEvent event = new EventBus.PlayerMovedEvent();
56+
event.player = player;
57+
eventBus.post(event);
58+
}
59+
} finally {
60+
running = false;
61+
62+
}
63+
64+
}
65+
}

src/main/java/io/rudin/minetest/tileserver/module/ServiceModule.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@
88
import io.rudin.minetest.tileserver.ColorTable;
99
import io.rudin.minetest.tileserver.provider.ColorTableProvider;
1010
import io.rudin.minetest.tileserver.provider.ExecutorProvider;
11+
import io.rudin.minetest.tileserver.service.EventBus;
1112
import io.rudin.minetest.tileserver.service.TileCache;
1213
import io.rudin.minetest.tileserver.service.impl.DatabaseTileCache;
14+
import io.rudin.minetest.tileserver.service.impl.EventBusImpl;
1315

1416
public class ServiceModule extends AbstractModule {
1517

1618
@Override
1719
protected void configure() {
1820
bind(TileCache.class).to(DatabaseTileCache.class);
1921
//bind(TileCache.class).to(FileTileCache.class);
22+
bind(EventBus.class).to(EventBusImpl.class);
2023
bind(ColorTable.class).toProvider(ColorTableProvider.class);
2124
bind(ExecutorService.class).toProvider(ExecutorProvider.class);
2225
bind(ScheduledExecutorService.class).toProvider(ExecutorProvider.class);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.rudin.minetest.tileserver.service;
2+
3+
import io.rudin.minetest.tileserver.blockdb.tables.pojos.Player;
4+
5+
public interface EventBus {
6+
7+
void post(Object obj);
8+
9+
void register(Object listener);
10+
11+
class TileChangedEvent {
12+
public int x,y,zoom;
13+
public int mapblockX, mapblockZ;
14+
}
15+
16+
class PlayerMovedEvent {
17+
public Player player;
18+
}
19+
20+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.rudin.minetest.tileserver.service.impl;
2+
3+
import io.rudin.minetest.tileserver.TileServer;
4+
import io.rudin.minetest.tileserver.blockdb.tables.Player;
5+
import io.rudin.minetest.tileserver.service.EventBus;
6+
7+
import javax.inject.Singleton;
8+
9+
@Singleton
10+
public class EventBusImpl implements EventBus {
11+
12+
private final com.google.common.eventbus.EventBus eventBus = new com.google.common.eventbus.EventBus();
13+
14+
@Override
15+
public void post(Object obj) {
16+
17+
if (obj instanceof PlayerMovedEvent){
18+
PlayerMovedEvent e = (PlayerMovedEvent)obj;
19+
System.out.println("Player-move: " + e.player.getName() + " @" + e.player.getPosx() + "/" + e.player.getPosz());
20+
}
21+
22+
if (obj instanceof TileChangedEvent){
23+
//TileChangedEvent e = (TileChangedEvent)obj;
24+
//System.out.println("Mapblock changed: " + e.mapblockX + "/" + e.mapblockZ + " (Coordinates: " + e.mapblockX*16 + "/" + e.mapblockZ*16 + ") @ zoom " + e.zoom);
25+
}
26+
27+
eventBus.post(obj);
28+
}
29+
30+
@Override
31+
public void register(Object listener) {
32+
eventBus.register(listener);
33+
}
34+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.rudin.minetest.tileserver.ws;
2+
3+
import org.eclipse.jetty.websocket.api.Session;
4+
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
5+
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
6+
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
7+
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
8+
9+
import java.io.IOException;
10+
import java.util.Queue;
11+
import java.util.concurrent.ConcurrentLinkedQueue;
12+
13+
@WebSocket
14+
public class WebSocketHandler {
15+
16+
public static final Queue<Session> sessions = new ConcurrentLinkedQueue<>();
17+
18+
@OnWebSocketConnect
19+
public void connected(Session session) {
20+
sessions.add(session);
21+
}
22+
23+
@OnWebSocketClose
24+
public void closed(Session session, int statusCode, String reason) {
25+
sessions.remove(session);
26+
}
27+
28+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package io.rudin.minetest.tileserver.ws;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.google.common.eventbus.Subscribe;
5+
import io.rudin.minetest.tileserver.service.EventBus;
6+
import org.eclipse.jetty.websocket.api.Session;
7+
8+
import javax.inject.Inject;
9+
import javax.inject.Singleton;
10+
11+
@Singleton
12+
public class WebSocketUpdater {
13+
14+
@Inject
15+
public WebSocketUpdater(EventBus eventBus){
16+
this.eventBus = eventBus;
17+
this.mapper = new ObjectMapper();
18+
}
19+
20+
private final EventBus eventBus;
21+
22+
private final ObjectMapper mapper;
23+
24+
public void init(){
25+
eventBus.register(this);
26+
}
27+
28+
public static class EventContainer {
29+
public String type;
30+
public Object data;
31+
}
32+
33+
@Subscribe void onPlayerMove(EventBus.PlayerMovedEvent e){
34+
try {
35+
EventContainer container = new EventContainer();
36+
container.data = e;
37+
container.type = "player-move";
38+
String json = mapper.writeValueAsString(container);
39+
40+
for (Session session : WebSocketHandler.sessions) {
41+
try {
42+
session.getRemote().sendString(json);
43+
44+
} catch (Exception e3) {
45+
//TODO
46+
}
47+
}
48+
} catch (Exception e2){
49+
e2.printStackTrace();
50+
}
51+
52+
}
53+
54+
@Subscribe void onTileUpdate(EventBus.TileChangedEvent e){
55+
try {
56+
EventContainer container = new EventContainer();
57+
container.data = e;
58+
container.type = "tile-update";
59+
String json = mapper.writeValueAsString(container);
60+
61+
for (Session session : WebSocketHandler.sessions) {
62+
try {
63+
session.getRemote().sendString(json);
64+
65+
} catch (Exception e3) {
66+
//TODO
67+
}
68+
}
69+
} catch (Exception e2){
70+
e2.printStackTrace();
71+
}
72+
73+
}
74+
75+
}

0 commit comments

Comments
 (0)