build static method

Future<RustSetonixPlugin> build(
  1. RustPlugin builder(
    1. PluginCallback
    ),
  2. PluginServerInterface server, {
  3. void onPrint(
    1. String
    )?,
  4. ItemLocation? location,
  5. String storageKey = '',
})

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;
}