Skip to content

Commit

Permalink
maybe fix null pointer in config
Browse files Browse the repository at this point in the history
  • Loading branch information
MrNavaStar committed Dec 16, 2024
1 parent 8cb4b20 commit 3d8b2e7
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public enum Action {

public enum Propagation {
ALL,
NEXT_SERVER,
PLAYER,
NONE
}

Expand All @@ -40,6 +40,7 @@ public static class Meta {
private Action action = Action.NONE;
private Topic topic;
private Propagation propagation = Propagation.ALL;
private boolean persist = true;
}

private static final ObjectSerializer serializer = new ObjectSerializer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public static void reloadBlacklists() {

protected static DataBundle createPlayerDataBundle(ServerPlayer player) {
DataBundle data = new DataBundle();
data.meta().propagation(DataBundle.Propagation.NEXT_SERVER);
data.meta().propagation(DataBundle.Propagation.PLAYER);
Singularity.SEND_DATA.getInvoker().trigger(player, data);
return data;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.mrnavastar.singularity.loader;

import com.google.common.collect.Sets;
import lombok.Getter;
import me.mrnavastar.protoweaver.proxy.api.ProtoProxy;
import me.mrnavastar.protoweaver.proxy.api.ProtoServer;
Expand All @@ -19,32 +20,38 @@
public class SingularityConfig {

@Getter
public static class GroupStore {
private final String groupName;
public static class SyncGroup {
private final String name;
private final Set<ProtoServer> servers = Sets.newConcurrentHashSet();
private final Settings settings;
private final ConcurrentHashMap<String, DataStore> topics = new ConcurrentHashMap<>();

public GroupStore(String groupName) {
this.groupName = groupName;
topics.put(Constants.PLAYER_TOPIC, SQLib.getDatabase().dataStore(Constants.SINGULARITY_ID, "static_" + groupName + "_player_data"));
public SyncGroup(String name, Settings settings) {
this.name = name;
this.settings = settings;
topics.put(Constants.PLAYER_TOPIC, SQLib.getDatabase().dataStore(Constants.SINGULARITY_ID, "static_" + name + "_player_data"));
}

public GroupStore() {
this.groupName = "default";
public SyncGroup() {
this.name = "default";
this.settings = new Settings();
topics.put(Constants.PLAYER_TOPIC, SQLib.getDatabase().dataStore(Constants.SINGULARITY_ID, "default_player_data"));
}

public void addServer(ProtoServer server) {
servers.add(server);
}

public DataStore getTopicStore(Topic topic) {
return Optional.ofNullable(topics.get(topic.topic())).orElseGet(() -> {
DataStore store = SQLib.getDatabase().dataStore(Constants.SINGULARITY_ID, "static_" + groupName + "_" + topic.databaseKey());
DataStore store = SQLib.getDatabase().dataStore(Constants.SINGULARITY_ID, "static_" + name + "_" + topic.databaseKey());
topics.put(topic.topic(), store);
return store;
});
}
}

private static final ConcurrentHashMap<ProtoServer, String> groups = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<ProtoServer, Settings> settings = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, GroupStore> groupStores = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, SyncGroup> groups = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, DataStore> globalStores = new ConcurrentHashMap<>();
private static final ArrayList<String> blacklists = new ArrayList<>();

Expand All @@ -60,12 +67,8 @@ public DataStore getTopicStore(Topic topic) {
registerBlacklist("singularity.xp");
}

public static Optional<Settings> getServerSettings(ProtoServer server) {
return Optional.ofNullable(settings.get(server));
}

public static Optional<GroupStore> getServerStore(ProtoServer server) {
return Optional.ofNullable(groups.get(server)).map(groupStores::get);
public static Optional<SyncGroup> getSyncGroup(ProtoServer server) {
return groups.values().stream().filter(group -> group.getServers().contains(server)).findFirst();
}

public static DataStore getGlobalStore(Topic topic) {
Expand All @@ -76,12 +79,6 @@ public static DataStore getGlobalStore(Topic topic) {
});
}

public static List<ProtoServer> getSameGroup(ProtoServer server) {
return Optional.ofNullable(groups.get(server))
.map(mainGroup -> groups.entrySet().stream().filter(entry -> entry.getValue().equals(mainGroup) && !entry.getKey().equals(server))
.map(Map.Entry::getKey).toList()).orElseGet(ArrayList::new);
}

public static void registerBlacklist(String name) {
blacklists.add(name);
}
Expand Down Expand Up @@ -117,25 +114,21 @@ public static void load(Logger logger) {
if (s.get("singularity.whitelist") instanceof Boolean enabled) groupSettings.syncWhitelist = enabled;
if (s.get("singularity.bans") instanceof Boolean enabled) groupSettings.syncBans = enabled;

groupStores.put(groupName, new GroupStore(groupName));
SyncGroup store = new SyncGroup(groupName, groupSettings);
groups.put("config_" + groupName, store);

ProtoProxy.getRegisteredServers().stream()
.filter(server -> List.of(servers.split("\n")).contains(server.getName()))
.forEach(server -> {
settings.put(server, groupSettings);
groups.put(server, "config_" + groupName);
});
.forEach(store::addServer);
});
});
});
} catch (FileNotFoundException ignore) {
logger.info("No config found, loading defaults");

groupStores.put("default", new GroupStore());
ProtoProxy.getRegisteredServers().forEach(server -> {
settings.put(server, new Settings().setDefault());
groups.put(server, "default");
});
SyncGroup group = new SyncGroup();
groups.put(group.getName(), group);
ProtoProxy.getRegisteredServers().forEach(group::addServer);
}
}
}
45 changes: 26 additions & 19 deletions proxy/src/main/java/me/mrnavastar/singularity/loader/Velocity.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void onServerPreConnect(ServerPreConnectEvent event) {
s.flatMap(current -> ProtoProxy.getConnectedServer(WORMHOLE, current.getServerInfo().getName())).ifPresent(server -> {
if (event.getPreviousServer() == null) {

SingularityConfig.getServerStore(server)
SingularityConfig.getSyncGroup(server)
.flatMap(store -> store.getTopicStore(PLAYER_TOPIC).getContainer("id", player.toString()))
.flatMap(c -> c.get(DATA_BUNDLE, "data"))
.map(data -> data.meta(new DataBundle.Meta().id(player.toString()).topic(PLAYER_TOPIC).action(DataBundle.Action.PUT)))
Expand All @@ -85,7 +85,7 @@ public void onServerPreConnect(ServerPreConnectEvent event) {
public void onReady(ProtoConnection connection) {
ProtoProxy.getRegisteredServer(connection.getRemoteAddress()).ifPresent(s -> {
server = s;
SingularityConfig.getServerSettings(server).ifPresent(connection::send);
SingularityConfig.getSyncGroup(server).ifPresent(group -> connection.send(group.getSettings()));
});
}

Expand All @@ -102,56 +102,63 @@ public void handlePacket(ProtoConnection connection, Object packet) {
// Process data bundle actions such as requesting and removing data
case DataBundle.Meta meta -> {
switch (meta.action()) {
case GET -> SingularityConfig.getServerStore(server)
case GET -> SingularityConfig.getSyncGroup(server)
.flatMap(store -> store.getTopicStore(meta.topic()).getContainer("id", meta.id()))
.flatMap(c -> c.get(DATA_BUNDLE, "data"))
.ifPresentOrElse(data -> connection.send(data.meta(meta)), () -> connection.send(meta));

case REMOVE -> SingularityConfig.getServerStore(server)
case REMOVE -> SingularityConfig.getSyncGroup(server)
.flatMap(store -> store.getTopicStore(meta.topic()).getContainer("id", meta.id()))
.ifPresent(DataContainer::delete);
}
}

case DataBundle data -> {
if (!DataBundle.Action.PUT.equals(data.meta().action())) return;
Topic topic = data.meta().topic();
case DataBundle bundle -> {
if (!DataBundle.Action.PUT.equals(bundle.meta().action())) return;
Topic topic = bundle.meta().topic();

Stream<ProtoServer> servers;
if (topic.global()) servers = ProtoProxy.getConnectedServers(WORMHOLE).stream();
else servers = SingularityConfig.getSameGroup(server).stream();
else {
Optional<SingularityConfig.SyncGroup> group = SingularityConfig.getSyncGroup(server);
if (group.isEmpty()) return;
servers = group.get().getServers().stream();
}

// Forward data to subscribed servers
servers.filter(s -> {
DataBundle.Propagation propagation = data.meta().propagation();
servers.filter(s -> !s.equals(server))
.filter(s -> {
DataBundle.Propagation propagation = bundle.meta().propagation();
if (propagation.equals(DataBundle.Propagation.ALL)) return true;
if (propagation.equals(DataBundle.Propagation.NONE)) return false;

// if propagation is set to NEXT_SERVER
//TODO: This is maybe a race condition
// if propagation is set to PLAYER
// TODO: This is maybe a race condition
try {
UUID player = UUID.fromString(data.meta().id());
UUID player = UUID.fromString(bundle.meta().id());
Optional<ProtoServer> location = Optional.ofNullable(playerLocations.get(player));
return location.isPresent() && location.get().equals(s);
} catch (IllegalArgumentException ignore) {
return false;
}
})
.filter(s -> subs.getOrDefault(s, new HashSet<>()).contains(topic))
.forEach(s -> s.getConnection().send(data));
.forEach(s -> s.getConnection().send(bundle));

if (!bundle.meta().persist()) return;

// Store data in database
if (topic.global()) {
SingularityConfig.getGlobalStore(topic)
.getOrCreateDefaultContainer(JavaTypes.STRING, "id", data.meta().id())
.put(DATA_BUNDLE, "data", data);
.getOrCreateDefaultContainer(JavaTypes.STRING, "id", bundle.meta().id())
.put(DATA_BUNDLE, "data", bundle);
return;
}

SingularityConfig.getServerStore(server)
SingularityConfig.getSyncGroup(server)
.ifPresent(store -> store.getTopicStore(topic)
.getOrCreateDefaultContainer(JavaTypes.STRING, "id", data.meta().id())
.put(DATA_BUNDLE, "data", data));
.getOrCreateDefaultContainer(JavaTypes.STRING, "id", bundle.meta().id())
.put(DATA_BUNDLE, "data", bundle));
}
default -> WORMHOLE.logWarn("Ignoring unknown packet: " + packet);
}
Expand Down

0 comments on commit 3d8b2e7

Please sign in to comment.