Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 56 additions & 7 deletions src/main/java/city/makeour/fiwarecraft/App.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
package city.makeour.fiwarecraft;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;

import city.makeour.fiwarecraft.client.FcMocClient;
import city.makeour.fiwarecraft.model.Server;
import city.makeour.moc.MocClient;

/**
* Fiwarecraft plugin main class
*/
public class App extends JavaPlugin {
public class App extends JavaPlugin implements Listener {

protected FcMocClient mocClient;
private static final String BASE_ENTITY_ID = "test-server-001";
private static final int GRID_SIZE = 64; // グリッドサイズ(ブロック単位)
private Map<String, Integer> lastGridCounts = new HashMap<>();

/**
* デフォルトのコンストラクタ
Expand All @@ -40,18 +48,59 @@ public void onEnable() {
getLogger().severe("Authentication failed. Please check your environment variables for Cognito credentials.");
return;
}
this.mocClient.sendPing("urn:ngsi-ld:ping:test-serer-001", true);
this.mocClient.sendPing(BASE_ENTITY_ID, true);
getServer().getPluginManager().registerEvents(this, this);

// ヒートマップ更新を60秒ごとに実行(CPU削減)
getServer().getScheduler().scheduleSyncRepeatingTask(this,
() -> updatePlayerHeatmap(), 0L, 1200L);

getLogger().info("Send ping");
}


private void updatePlayerHeatmap() {
Map<String, Integer> gridCounts = new HashMap<>();
int totalPlayers = 0;

for (Player player : getServer().getOnlinePlayers()) {
totalPlayers++;
String gridId = getGridId(player);
gridCounts.put(gridId, gridCounts.getOrDefault(gridId, 0) + 1);
}

if (!Objects.equals(lastGridCounts, gridCounts)) {
Server server = new Server()
.playerCount(totalPlayers)
.heatmap(gridCounts)
.status("ONLINE")
.updatedAt(LocalDateTime.now());

this.mocClient.sendServer(BASE_ENTITY_ID, server);
lastGridCounts = new HashMap<>(gridCounts);
getLogger().info("Updated server: " + totalPlayers + " players, " + gridCounts.size() + " grids");
}
}

private String getGridId(Player player) {
int gridX = (int) player.getLocation().getX() / GRID_SIZE;
int gridZ = (int) player.getLocation().getZ() / GRID_SIZE;
int gridY = (int) player.getLocation().getY() / GRID_SIZE;
return String.format("urn:ngsi-ld:Heatmap:grid-%d-%d-%d", gridX, gridY, gridZ);
}

@Override
public void onDisable() {
getLogger().info("Fiwarecraft plugin has been disabled!");
if (this.mocClient != null) {
// onEnableと同じ Entity ID を指定して、ステータスを false にして送信
this.mocClient.sendPing("urn:ngsi-ld:ping:test-serer-001", false);
getLogger().info("Send ping (offline)");
this.mocClient.sendPing(BASE_ENTITY_ID, false);
Server server = new Server()
.playerCount(0)
.heatmap(new HashMap<>())
.status("OFFLINE")
.updatedAt(LocalDateTime.now());
this.mocClient.sendServer(BASE_ENTITY_ID, server);
getLogger().info("Send ping and server status (offline)");
}
}
}
68 changes: 68 additions & 0 deletions src/main/java/city/makeour/fiwarecraft/client/FcMocClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import city.makeour.moc.MocClient;
import city.makeour.fiwarecraft.model.Ping;
import city.makeour.fiwarecraft.model.PlayerCount;
import city.makeour.fiwarecraft.model.Server;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
Expand Down Expand Up @@ -107,6 +109,72 @@ public void sendPing(String entityId, boolean status) {
}


public void sendPlayerCount(String entityId, int count) {
PlayerCount entity = new PlayerCount();
entity.setId(entityId);
entity.setType("PlayerCount");
entity.setCount(count);
entity.setUpdatedAt(LocalDateTime.now());

if (this.fiwareService != null && !this.fiwareService.isEmpty()) {
mocClient.setFiwareService(this.fiwareService);
}

var resp = mocClient.updateEntity(entityId, "PlayerCount", entity);
if (resp != null) {
System.out.println("PlayerCount Upserted: " + count);
}
}

public void sendServer(String entityId, Server server) {
if (server.getType() == null) {
server.setType("Server");
}

if (server.getId() == null) {
server.setId(entityId);
}

if (server.getUpdatedAt() == null) {
server.setUpdatedAt(LocalDateTime.now());
}

if (this.fiwareService != null && !this.fiwareService.isEmpty()) {
mocClient.setFiwareService(this.fiwareService);
}

var resp = mocClient.updateEntity(entityId, "Server", server);
if (resp != null) {
System.out.println("Server Upserted: " + server.getPlayerCount() + " players, " +
server.getHeatmap().size() + " grids, status=" + server.getStatus());
}
}

public void sendServerData(String entityId, Map<String, Integer> gridCounts) {
Map<String, Object> heatmapGrids = new HashMap<>();
for (String gridId : gridCounts.keySet()) {
Map<String, Object> gridData = new HashMap<>();
gridData.put("gridId", gridId);
gridData.put("count", gridCounts.get(gridId));
heatmapGrids.put(gridId, gridData);
}

Map<String, Object> serverData = new HashMap<>();
serverData.put("id", entityId);
serverData.put("type", "Server");
serverData.put("heatmapGrids", heatmapGrids);
serverData.put("recordedAt", LocalDateTime.now());

if (this.fiwareService != null && !this.fiwareService.isEmpty()) {
mocClient.setFiwareService(this.fiwareService);
}

var resp = mocClient.updateEntity(entityId, "Server", serverData);
if (resp != null) {
System.out.println("Server Data Sent: " + gridCounts.size() + " grids updated");
}
}

public void setFiwareService(String fiwareService) {
this.fiwareService = fiwareService;
}
Expand Down
57 changes: 57 additions & 0 deletions src/main/java/city/makeour/fiwarecraft/model/PlayerCount.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package city.makeour.fiwarecraft.model;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.annotation.Nonnull;
import java.time.LocalDateTime;

public class PlayerCount extends NgsiV2Entity {

public static final String JSON_PROPERTY_COUNT = "count";
private int count;

public static final String JSON_PROPERTY_UPDATED_AT = "updatedAt";
private LocalDateTime updatedAt;

public PlayerCount() {
this.count = 0;
}

public PlayerCount count(int count) {
this.count = count;
return this;
}

public PlayerCount updatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
return this;
}

@Nonnull
@JsonProperty(JSON_PROPERTY_COUNT)
@JsonInclude(JsonInclude.Include.ALWAYS)
public int getCount() {
return this.count;
}

@JsonProperty(JSON_PROPERTY_COUNT)
@JsonInclude(JsonInclude.Include.ALWAYS)
public void setCount(int count) {
this.count = count;
}

@JsonProperty(JSON_PROPERTY_UPDATED_AT)
@JsonInclude(JsonInclude.Include.ALWAYS)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
public LocalDateTime getUpdatedAt() {
return this.updatedAt;
}

@JsonProperty(JSON_PROPERTY_UPDATED_AT)
@JsonInclude(JsonInclude.Include.ALWAYS)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
}
103 changes: 103 additions & 0 deletions src/main/java/city/makeour/fiwarecraft/model/Server.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package city.makeour.fiwarecraft.model;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.annotation.Nonnull;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

public class Server extends NgsiV2Entity {

public static final String JSON_PROPERTY_PLAYER_COUNT = "playerCount";
private int playerCount;

public static final String JSON_PROPERTY_HEATMAP = "heatmap";
private Map<String, Integer> heatmap;

public static final String JSON_PROPERTY_STATUS = "status";
private String status;

public static final String JSON_PROPERTY_UPDATED_AT = "updatedAt";
private LocalDateTime updatedAt;

public Server() {
this.playerCount = 0;
this.heatmap = new HashMap<>();
this.status = "OFFLINE";
}

public Server playerCount(int playerCount) {
this.playerCount = playerCount;
return this;
}

public Server heatmap(Map<String, Integer> heatmap) {
this.heatmap = heatmap;
return this;
}

public Server status(String status) {
this.status = status;
return this;
}

public Server updatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
return this;
}

@Nonnull
@JsonProperty(JSON_PROPERTY_PLAYER_COUNT)
@JsonInclude(JsonInclude.Include.ALWAYS)
public int getPlayerCount() {
return this.playerCount;
}

@JsonProperty(JSON_PROPERTY_PLAYER_COUNT)
@JsonInclude(JsonInclude.Include.ALWAYS)
public void setPlayerCount(int playerCount) {
this.playerCount = playerCount;
}

@Nonnull
@JsonProperty(JSON_PROPERTY_HEATMAP)
@JsonInclude(JsonInclude.Include.ALWAYS)
public Map<String, Integer> getHeatmap() {
return this.heatmap;
}

@JsonProperty(JSON_PROPERTY_HEATMAP)
@JsonInclude(JsonInclude.Include.ALWAYS)
public void setHeatmap(Map<String, Integer> heatmap) {
this.heatmap = heatmap;
}

@Nonnull
@JsonProperty(JSON_PROPERTY_STATUS)
@JsonInclude(JsonInclude.Include.ALWAYS)
public String getStatus() {
return this.status;
}

@JsonProperty(JSON_PROPERTY_STATUS)
@JsonInclude(JsonInclude.Include.ALWAYS)
public void setStatus(String status) {
this.status = status;
}

@JsonProperty(JSON_PROPERTY_UPDATED_AT)
@JsonInclude(JsonInclude.Include.ALWAYS)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
public LocalDateTime getUpdatedAt() {
return this.updatedAt;
}

@JsonProperty(JSON_PROPERTY_UPDATED_AT)
@JsonInclude(JsonInclude.Include.ALWAYS)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
}
Loading