Introduce backend synchronization system for Velocity and WebsiteBackend

This commit is contained in:
2025-07-20 00:06:19 +02:00
parent fd57ba43e9
commit 7b01f11b5b
6 changed files with 186 additions and 0 deletions
@@ -0,0 +1,96 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.velocitycore;
import de.steamwar.data.SyncCommands;
import de.steamwar.sql.Event;
import de.steamwar.sql.EventFight;
import de.steamwar.sql.SteamwarUser;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
public class BackendSync implements Runnable {
private static final Path syncPath = new File("/run/sync").toPath();
private final Thread thread;
private final WatchService watchService;
public BackendSync() {
try {
watchService
= FileSystems.getDefault().newWatchService();
} catch (IOException e) {
throw new SecurityException("Could not create watch service", e);
}
thread = new Thread(this, "BackendSync");
thread.start();
}
public void stop() {
try {
watchService.close();
thread.join();
} catch (IOException | InterruptedException e) {
Thread.currentThread().interrupt();
}
}
private void handleCommand(String name) {
try {
String[] parts = name.split("\\.");
switch (parts[0]) {
case SyncCommands.RELOAD_EVENT -> EventFight.loadAllComingFights();
case SyncCommands.RELOAD_PLAYER -> SteamwarUser.invalidate(Integer.parseInt(parts[1]));
default -> VelocityCore.getLogger().warning("Unknown command: " + name);
}
} catch (Exception e) {
VelocityCore.getLogger().throwing(this.getClass().getName(), "handleCommand", e);
}
}
@Override
public void run() {
try {
syncPath.register(watchService,
java.nio.file.StandardWatchEventKinds.ENTRY_CREATE);
WatchKey key;
while ((key = watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
String command = event.context().toString();
handleCommand(command);
if (!VelocityCore.get().getConfig().isEventmode()) {
Path path = syncPath.resolve((Path) event.context());
Files.delete(path);
}
}
}
} catch (InterruptedException | ClosedWatchServiceException ignored) {
Thread.currentThread().interrupt();
} catch (Exception e) {
VelocityCore.getLogger().throwing(this.getClass().getName(), "run", e);
}
}
}
@@ -95,6 +95,7 @@ public class VelocityCore implements ReloadablePlugin {
private Config config;
private ErrorLogger errorLogger;
private TablistManager tablistManager;
private BackendSync backendSync;
@Getter
private TeamCommand teamCommand;
@@ -147,6 +148,8 @@ public class VelocityCore implements ReloadablePlugin {
new ReplayMod();
new FML2();
backendSync = new BackendSync();
new ConnectionListener();
new ChatListener();
new BanListener();
@@ -268,6 +271,8 @@ public class VelocityCore implements ReloadablePlugin {
logger.log(Level.SEVERE, "Could not shutdown discord bot", e);
}
backendSync.stop();
if(tablistManager != null)
tablistManager.disable();
errorLogger.unregister();