Skip to content

Commit 586ab05

Browse files
authored
Merge pull request #3 from AndNowWhat/fix/persist-groups
Persist connection groups to ~/.botwithus/groups.json
2 parents 286f6c3 + 55bc801 commit 586ab05

8 files changed

Lines changed: 90 additions & 12 deletions

File tree

cli/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ val lwjglNatives = "natives-windows"
1111
dependencies {
1212
implementation(project(":api"))
1313
implementation(project(":core"))
14+
implementation("com.google.code.gson:gson:2.11.0")
1415
implementation("io.github.spair:imgui-java-app:$imguiVersion")
1516
runtimeOnly("io.github.spair:imgui-java-natives-windows:$imguiVersion")
1617
runtimeOnly("org.lwjgl:lwjgl:$lwjglVersion:$lwjglNatives")

cli/src/main/java/com/botwithus/bot/cli/CliContext.java

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121

2222
import com.botwithus.bot.core.runtime.ScriptRunner;
2323

24+
import com.google.gson.Gson;
25+
import com.google.gson.GsonBuilder;
26+
import com.google.gson.reflect.TypeToken;
27+
2428
import java.awt.image.BufferedImage;
2529
import java.io.PrintStream;
2630
import java.nio.file.Files;
@@ -297,14 +301,69 @@ public void openConfigPanel(ScriptRunner runner) {
297301
if (configPanelOpener != null) configPanelOpener.accept(runner);
298302
}
299303

300-
// --- Connection Group management ---
304+
// --- Connection Group management & persistence ---
305+
306+
private static final Path GROUPS_FILE = Path.of(System.getProperty("user.home"), ".botwithus", "groups.json");
307+
308+
/** Simple DTO for JSON serialization of a group. */
309+
private static class GroupData {
310+
String description;
311+
List<String> members;
312+
GroupData() {}
313+
GroupData(String description, List<String> members) {
314+
this.description = description;
315+
this.members = members;
316+
}
317+
}
318+
319+
/** Loads persisted groups from ~/.botwithus/groups.json. */
320+
public void loadGroups() {
321+
if (!Files.exists(GROUPS_FILE)) return;
322+
try {
323+
String json = Files.readString(GROUPS_FILE);
324+
Gson gson = new Gson();
325+
Map<String, GroupData> data = gson.fromJson(json,
326+
new TypeToken<LinkedHashMap<String, GroupData>>() {}.getType());
327+
if (data != null) {
328+
groups.clear();
329+
for (var entry : data.entrySet()) {
330+
ConnectionGroup group = new ConnectionGroup(entry.getKey());
331+
GroupData gd = entry.getValue();
332+
if (gd.description != null) group.setDescription(gd.description);
333+
if (gd.members != null) gd.members.forEach(group::add);
334+
groups.put(entry.getKey(), group);
335+
}
336+
}
337+
} catch (Exception e) {
338+
System.err.println("[CliContext] Failed to load groups: " + e.getMessage());
339+
}
340+
}
341+
342+
/** Persists current groups to ~/.botwithus/groups.json. */
343+
void saveGroups() {
344+
try {
345+
Files.createDirectories(GROUPS_FILE.getParent());
346+
Gson gson = new GsonBuilder().setPrettyPrinting().create();
347+
Map<String, GroupData> data = new LinkedHashMap<>();
348+
for (var entry : groups.entrySet()) {
349+
ConnectionGroup g = entry.getValue();
350+
data.put(entry.getKey(), new GroupData(g.getDescription(), new ArrayList<>(g.getConnectionNames())));
351+
}
352+
Files.writeString(GROUPS_FILE, gson.toJson(data));
353+
} catch (Exception e) {
354+
System.err.println("[CliContext] Failed to save groups: " + e.getMessage());
355+
}
356+
}
301357

302358
public void createGroup(String name) {
303359
groups.put(name, new ConnectionGroup(name));
360+
saveGroups();
304361
}
305362

306363
public boolean deleteGroup(String name) {
307-
return groups.remove(name) != null;
364+
boolean removed = groups.remove(name) != null;
365+
if (removed) saveGroups();
366+
return removed;
308367
}
309368

310369
public ConnectionGroup getGroup(String name) {
@@ -315,6 +374,22 @@ public Map<String, ConnectionGroup> getGroups() {
315374
return Collections.unmodifiableMap(groups);
316375
}
317376

377+
public void addToGroup(String groupName, String connectionName) {
378+
ConnectionGroup group = groups.get(groupName);
379+
if (group != null) {
380+
group.add(connectionName);
381+
saveGroups();
382+
}
383+
}
384+
385+
public void removeFromGroup(String groupName, String connectionName) {
386+
ConnectionGroup group = groups.get(groupName);
387+
if (group != null) {
388+
group.remove(connectionName);
389+
saveGroups();
390+
}
391+
}
392+
318393
/**
319394
* Returns the list of active (connected) Connection objects for a group.
320395
* Connections that are in the group but not currently connected are skipped.

cli/src/main/java/com/botwithus/bot/cli/ClientManager.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public void setGroupDescription(String groupName, String description) {
113113
ConnectionGroup group = ctx.getGroup(groupName);
114114
if (group != null) {
115115
group.setDescription(description);
116+
ctx.saveGroups();
116117
}
117118
}
118119

@@ -124,17 +125,15 @@ public Set<String> getGroupMembers(String groupName) {
124125

125126
@Override
126127
public boolean addToGroup(String groupName, String clientName) {
127-
ConnectionGroup group = ctx.getGroup(groupName);
128-
if (group == null) return false;
129-
group.add(clientName);
128+
if (ctx.getGroup(groupName) == null) return false;
129+
ctx.addToGroup(groupName, clientName);
130130
return true;
131131
}
132132

133133
@Override
134134
public boolean removeFromGroup(String groupName, String clientName) {
135-
ConnectionGroup group = ctx.getGroup(groupName);
136-
if (group == null) return false;
137-
group.remove(clientName);
135+
if (ctx.getGroup(groupName) == null) return false;
136+
ctx.removeFromGroup(groupName, clientName);
138137
return true;
139138
}
140139

cli/src/main/java/com/botwithus/bot/cli/JBotCli.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public static void main(String[] args) {
4040

4141
PrintStream out = logCapture.getOriginalOut();
4242
CliContext ctx = new CliContext(logBuffer, logCapture);
43+
ctx.loadGroups();
4344
CommandRegistry registry = new CommandRegistry();
4445

4546
// Register commands

cli/src/main/java/com/botwithus/bot/cli/command/impl/GroupCommand.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ private void addToGroup(String groupName, String connName, CliContext ctx) {
7575
ctx.out().println("'" + connName + "' is already in group '" + groupName + "'.");
7676
return;
7777
}
78-
group.add(connName);
78+
ctx.addToGroup(groupName, connName);
7979
ctx.out().println("Added '" + connName + "' to group '" + groupName + "'.");
8080
}
8181

@@ -93,7 +93,7 @@ private void removeFromGroup(String groupName, String connName, CliContext ctx)
9393
ctx.out().println("'" + connName + "' is not in group '" + groupName + "'.");
9494
return;
9595
}
96-
group.remove(connName);
96+
ctx.removeFromGroup(groupName, connName);
9797
ctx.out().println("Removed '" + connName + "' from group '" + groupName + "'.");
9898
}
9999

cli/src/main/java/com/botwithus/bot/cli/gui/GroupsPanel.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public void render(CliContext ctx) {
135135
ImGui.sameLine(0, 12);
136136
ImGui.pushID("member_rm_" + grpIdx + "_" + memberIdx);
137137
if (ImGui.smallButton("Remove")) {
138-
group.remove(memberName);
138+
ctx.removeFromGroup(groupName, memberName);
139139
}
140140
ImGui.popID();
141141
memberIdx++;
@@ -167,7 +167,7 @@ private void renderAddConnectionDropdown(CliContext ctx, String groupName, Conne
167167
ImGui.popItemWidth();
168168
ImGui.sameLine();
169169
if (ImGui.smallButton("Add")) {
170-
group.add(names[selected.get()]);
170+
ctx.addToGroup(groupName, names[selected.get()]);
171171
}
172172
ImGui.popID();
173173
}

cli/src/main/java/com/botwithus/bot/cli/gui/ImGuiApp.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ protected void initImGui(Configuration config) {
126126
logCapture.install();
127127

128128
ctx = new CliContext(logBuffer, logCapture);
129+
ctx.loadGroups();
129130
ctx.setStreamManager(new StreamManager(outputBuffer, textureManager, guiOut));
130131

131132
ScriptProfileStore profileStore = new ScriptProfileStore();

cli/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module com.botwithus.bot.cli {
22
requires com.botwithus.bot.api;
33
requires com.botwithus.bot.core;
4+
requires com.google.gson;
45
requires imgui.binding;
56
requires imgui.app;
67
requires org.lwjgl;

0 commit comments

Comments
 (0)