Skip to content

Commit 22b161a

Browse files
committed
Add first basic working scripts feature in server
1 parent 3c9b848 commit 22b161a

File tree

17 files changed

+444
-33
lines changed

17 files changed

+444
-33
lines changed

api/lib/src/models/kick.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:dart_mappable/dart_mappable.dart';
22

33
part 'kick.mapper.dart';
44

5+
@MappableEnum()
56
enum KickReason {
67
kick,
78
ban,

api/lib/src/models/kick.mapper.dart

Lines changed: 63 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/lib/src/models/table.mapper.dart

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/lib/bloc/world/bloc.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ class _WorldServerInterfaceImpl implements ServerInterface {
3636
bloc._processEvent(NetworkerPacket(event, target));
3737
}
3838

39+
@override
40+
void print(String message, [String? plugin]) {
41+
// TODO: implement better logging
42+
}
43+
3944
@override
4045
WorldState get state => bloc.state.world;
4146

plugin/lib/src/events/model.dart

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import 'dart:async';
12
import 'dart:io';
3+
import 'dart:typed_data';
24

35
import 'package:dart_mappable/dart_mappable.dart';
46
import 'package:networker/networker.dart';
@@ -93,7 +95,45 @@ final class UserLeaveCallback {
9395
UserLeaveCallback({required this.channel, required this.info});
9496
}
9597

96-
@MappableClass()
98+
class _ConvertedConnectionInfo extends ConnectionInfo {
99+
final Uri address;
100+
101+
_ConvertedConnectionInfo(this.address);
102+
103+
@override
104+
FutureOr<void> close() {}
105+
106+
@override
107+
bool get isClosed => true;
108+
109+
@override
110+
FutureOr<void> sendMessage(Uint8List data) {}
111+
}
112+
113+
class ConnectionInfoMapper extends SimpleMapper<ConnectionInfo> {
114+
const ConnectionInfoMapper();
115+
116+
@override
117+
ConnectionInfo decode(Object value) {
118+
if (value is Map<String, Object?>) {
119+
return _ConvertedConnectionInfo(
120+
Uri.parse(value['address'] as String? ?? 'http://localhost'),
121+
);
122+
}
123+
return _ConvertedConnectionInfo(Uri.parse('http://localhost'));
124+
}
125+
126+
@override
127+
Object? encode(ConnectionInfo self) {
128+
return {
129+
'address': self is _ConvertedConnectionInfo
130+
? self.address.toString()
131+
: '',
132+
};
133+
}
134+
}
135+
136+
@MappableClass(includeCustomMappers: [ConnectionInfoMapper()])
97137
final class UserJoined extends LocalWorldEvent with UserJoinedMappable {
98138
final Channel channel;
99139
final ConnectionInfo info;

plugin/lib/src/events/model.mapper.dart

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugin/lib/src/plugin.dart

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ mixin ServerInterface {
2222
required String plugin,
2323
});
2424

25+
void print(String message, [String? plugin]);
26+
2527
WorldState get state;
2628
List<int> get players;
2729
}
@@ -32,16 +34,16 @@ final class PluginSystem {
3234

3335
PluginSystem({required this.server});
3436

35-
SetonixPlugin registerPlugin(
37+
Future<SetonixPlugin> registerPlugin(
3638
String name,
37-
SetonixPlugin Function(PluginServerInterface) pluginBuilder,
38-
) {
39+
FutureOr<SetonixPlugin> Function(PluginServerInterface) pluginBuilder,
40+
) async {
3941
final pluginServer = _PluginServerInterfaceImpl(server, name);
40-
final plugin = pluginBuilder(pluginServer);
42+
final plugin = await pluginBuilder(pluginServer);
4143
return _plugins[name] = plugin;
4244
}
4345

44-
SetonixPlugin registerLuauPlugin(
46+
Future<SetonixPlugin> registerLuauPlugin(
4547
String name,
4648
String code, {
4749
void Function(String)? onPrint,
@@ -52,6 +54,7 @@ final class PluginSystem {
5254
(pluginServer) => RustSetonixPlugin.build(
5355
(c) => LuauPlugin(code: code, callback: c),
5456
pluginServer,
57+
onPrint: (e) => server.print(e, name),
5558
),
5659
);
5760
}
@@ -83,7 +86,7 @@ final class PluginSystem {
8386
.getPack(location.namespace)
8487
?.getScript(location.id);
8588
if (data == null) return;
86-
registerLuauPlugin(name, data);
89+
registerLuauPlugin(name, data, onPrint: (e) => server.print(e, name));
8790
}
8891

8992
bool get _nativeEnabled => RustLib.instance.initialized;
@@ -167,14 +170,12 @@ final class RustSetonixPlugin extends SetonixPlugin {
167170

168171
RustSetonixPlugin._(super.server, this.plugin);
169172

170-
factory RustSetonixPlugin.build(
173+
static Future<RustSetonixPlugin> build(
171174
RustPlugin Function(PluginCallback) builder,
172175
PluginServerInterface server, {
173176
void Function(String)? onPrint,
174-
}) {
177+
}) async {
175178
final callback = PluginCallback.default_();
176-
final plugin = builder(callback);
177-
final instance = RustSetonixPlugin._(server, plugin);
178179
if (onPrint != null) {
179180
callback.changeOnPrint(onPrint: onPrint);
180181
}
@@ -195,13 +196,17 @@ final class RustSetonixPlugin extends SetonixPlugin {
195196
final state = server.state;
196197
return switch (field) {
197198
StateFieldAccess.info => state.info.toJson(),
198-
StateFieldAccess.table => state.table.toJson(),
199+
StateFieldAccess.tables => jsonEncode(
200+
state.data.getTables().toList(),
201+
),
199202
StateFieldAccess.tableName => jsonEncode(state.tableName),
200203
StateFieldAccess.players => jsonEncode(server.players),
201204
StateFieldAccess.teamMembers => jsonEncode(state.teamMembers),
202205
};
203206
},
204207
);
208+
final plugin = builder(callback);
209+
final instance = RustSetonixPlugin._(server, plugin);
205210
instance.eventSystem.on<WorldEvent>((e) {
206211
instance.plugin.runEvent(
207212
eventType: e.clientEvent.runtimeType.toString(),
@@ -211,6 +216,7 @@ final class RustSetonixPlugin extends SetonixPlugin {
211216
source: e.source,
212217
);
213218
});
219+
await instance.plugin.run();
214220
return instance;
215221
}
216222

plugin/lib/src/rust/api/plugin.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ abstract class PluginCallback implements RustOpaqueInterface {
2727
required FutureOr<String> Function(StateFieldAccess) stateFieldAccess,
2828
});
2929

30+
void changeTableAccess({
31+
required FutureOr<String> Function(String?) tableAccess,
32+
});
33+
3034
static PluginCallback default_() =>
3135
RustLib.instance.api.crateApiPluginPluginCallbackDefault();
3236
}
@@ -64,4 +68,4 @@ class EventResult {
6468
needsUpdate == other.needsUpdate;
6569
}
6670

67-
enum StateFieldAccess { table, tableName, info, players, teamMembers }
71+
enum StateFieldAccess { tableName, tables, info, players, teamMembers }

0 commit comments

Comments
 (0)