onClientEvent method
Implementation
Future<void> onClientEvent(
NetworkerPacket<WorldEvent> packet, {
bool force = false,
}) async {
final data = packet.data;
if (!packet.isServer &&
data is ClientWorldEvent &&
data is! AuthenticateRequest) {
final user = server.userManager.getUser(packet.channel);
if (user == null ||
!canProcessClientEvent(
user.roles,
data,
server.configManager.serverRoles,
)) {
server.log(
'Rejected ${data.runtimeType} from channel ${packet.channel}: '
'${user == null ? 'unauthenticated' : 'roles ${user.roles.join(', ')}'}',
level: LogLevel.warning,
);
return;
}
if (!isValidClientEvent(
data,
packet.channel,
state,
assetManager: assetManager,
allowManagementRequests: true,
)) {
server.log(
'Rejected invalid ${data.runtimeType} payload from channel '
'${packet.channel}.',
level: LogLevel.warning,
);
return;
}
if (await _handleManagementEvent(data, packet.channel)) return;
}
ServerResponse? process;
try {
process = await processClientEvent(
data is UserJoined ? null : data,
packet.channel,
state,
assetManager: assetManager,
allowServerEvents: packet.isServer,
// The dedicated server has already applied role authorization above.
// Peer-hosted games retain the shared API's authority-only default.
allowManagementRequests: true,
challengeManager: server.challengeManager,
userManager: server.userManager,
);
} catch (e) {
server.log('Error processing event: $e', level: LogLevel.error);
}
if (process == null) return;
switch (process) {
case UpdateServerResponse():
final event = Event(
serverEvent: process.main?.data,
target: process.main?.channel ?? kAnyChannel,
clientEvent: data,
source: packet.channel,
needsUpdate: process.needsUpdate,
worldName: worldName,
);
if (!force) {
await server.defaultWorld.pluginSystem.fire(event);
if (event.cancelled) return;
server.log(
'Processing event by ${event.source}: ${limitOutput(event.clientEvent)}, answered with ${limitOutput(event.serverEvent)}',
level: LogLevel.verbose,
);
}
switch (packet.data) {
case MessageRequest data:
server.log(
"Message by ${packet.channel}: ${data.message}",
level: LogLevel.info,
);
default:
}
_scheduledUpdates.add((event.serverEvent, process, event.needsUpdate));
final serverEvent = event.serverEvent;
if (serverEvent != null) {
await sendEvent(serverEvent, target: event.target);
}
for (final scheduled in event.scheduledEvents) {
await onClientEvent(scheduled, force: true);
}
case KickServerResponse():
server.kick(packet.channel, process.message);
}
if (data is AuthenticateRequest) {
final user = server.userManager.getUser(packet.channel);
if (user != null) {
final validRoles = {
kDefaultServerRole,
...user.roles.where(server.configManager.serverRoles.containsKey),
};
if (validRoles.length != user.roles.length ||
!validRoles.containsAll(user.roles)) {
await server.userManager.changeRoles(
'#${packet.channel}',
validRoles,
);
}
}
}
if (data is UserJoined || data is AuthenticateRequest) {
await server.broadcastServerState(this);
}
}