build static method
Implementation
static Future<RustSetonixPlugin> build(
RustPlugin Function(PluginCallback) builder,
PluginServerInterface server, {
void Function(String)? onPrint,
ItemLocation? location,
String storageKey = '',
}) async {
final callback = PluginCallback(
onPrint: onPrint ?? (s) {},
processEvent: (serializedEvent, force) async {
final event = WorldEventMapper.fromJson(serializedEvent);
await server.process(event, force: force ?? false);
},
sendEvent: (serializedEvent, target) async {
final event = WorldEventMapper.fromJson(serializedEvent);
if (event is! PlayableWorldEvent) {
throw StateError("Event is not PlayableWorldEvent");
}
await server.sendEvent(event, target: target ?? kAnyChannel);
},
stateFieldAccess: (field) {
final state = server.state;
return switch (field) {
StateFieldAccess.info => state.info.toJson(),
StateFieldAccess.tables => jsonEncode(
state.data.getTables().toList(),
),
StateFieldAccess.tableName => jsonEncode(state.tableName),
StateFieldAccess.players => jsonEncode(server.players),
StateFieldAccess.teamMembers => jsonEncode(state.teamMembers),
StateFieldAccess.gameRoles => jsonEncode(state.gameRoleMembers),
StateFieldAccess.game => jsonEncode(location?.id ?? 'unknown'),
StateFieldAccess.namespace => jsonEncode(
location?.namespace ?? 'unknown',
),
};
},
tableAccess: (tableName) {
if (server.state.tableName == tableName)
return server.state.table.toJson();
final table = server.state.data.getTable(tableName ?? '');
return table?.toJson() ?? "{}";
},
storageRead: () => server.getScriptState(storageKey),
storageWrite: (state) => server.setScriptState(storageKey, state),
);
final plugin = builder(callback);
final instance = RustSetonixPlugin._(server, plugin);
instance.eventSystem.on<WorldEvent>((e) async {
final serializedEvent = e.clientEvent.toJson();
// Runtime class names are minified in release web builds. The wire
// discriminator is the stable event name that Lua subscribes to.
final eventType = (jsonDecode(serializedEvent) as Map)['type'] as String;
final result = await instance.plugin.runEvent(
eventType: eventType,
event: serializedEvent,
serverEvent: e.serverEvent?.toJson(),
target: e.target,
source: e.source,
cancelled: e.cancelled,
);
e.cancelled = result.cancelled;
e.needsUpdate = result.needsUpdate;
final serverEvent = result.serverEvent;
if (serverEvent != null) {
e.serverEvent = ServerWorldEventMapper.fromJson(serverEvent);
}
e.scheduleEvents(
result.scheduledEvents.map((e) {
final event = WorldEventMapper.fromJson(e.$1);
if (event is! PlayableWorldEvent) {
return null;
}
return NetworkerPacket(event, e.$2);
}).nonNulls,
);
});
instance._leaveSubscription = instance.eventSystem.leave.listen((
event,
) async {
await instance.plugin.runEvent(
eventType: 'UserLeft',
event: jsonEncode({'type': 'UserLeft', 'channel': event.channel}),
source: event.channel,
target: kAnyChannel,
cancelled: false,
);
});
try {
await instance.plugin.run();
} catch (_) {
instance.dispose();
rethrow;
}
return instance;
}