TryCatch tail functions

This commit is contained in:
zontreck 2024-06-05 22:01:01 -07:00
parent 2a5774bd6d
commit d885485684
5 changed files with 22 additions and 192 deletions

View file

@ -16,12 +16,12 @@ class PacketServer {
print("Server now listening on port ${port}");
await for (var sock in socket!) {
S2CResponse response = S2CResponse();
print(
"New connection from ${sock.remoteAddress.address}:${sock.remotePort}");
try {
sock.listen((data) async {
S2CResponse response = S2CResponse();
try {
CompoundTag tag = await NbtIo.readFromStream(data);
StringBuilder builder = StringBuilder();
@ -33,8 +33,8 @@ class PacketServer {
request.decodeTag(tag);
PacketResponse reply = await request.handleServerPacket();
// Server uses NBT to communicate
// Server uses NBT to communicate
builder = StringBuilder();
Tag.writeStringifiedNamedTag(reply.replyDataTag, builder, 0);
@ -45,17 +45,10 @@ class PacketServer {
.put("error", StringTag.valueOf("Malformed request packet"));
print(
"Something went wrong, sending malformed request response\n${stack}\n\n${E}\n\n");
sock.add(
await NbtIo.writeToStream(response.encodeTag() as CompoundTag));
"Something went wrong. Malformed request? \n\n${E}\n\n${stack}\n\n\n\n");
} finally {
await sock.flush();
sock.close();
if (!shouldRestart) {
await socket!.close();
}
}
}, onDone: () {
sock.close();

View file

@ -85,10 +85,12 @@ Stream<List<int>> tail(final File file) async* {
Stream<Uint8List> _read() async* {
while (pos < len) {
final bytesRead = await randomAccess.readInto(buf);
pos += bytesRead;
try {
final bytesRead = await randomAccess.readInto(buf);
pos += bytesRead;
yield buf.sublist(0, bytesRead);
yield buf.sublist(0, bytesRead);
} catch (E) {}
}
}
@ -98,15 +100,22 @@ Stream<List<int>> tail(final File file) async* {
// Step 2: wait for modify events and read more bytes from file
await for (final event in file.watch(events: FileSystemEvent.modify)) {
if ((event as FileSystemModifyEvent).contentChanged) {
len = await (randomAccess.length());
yield* _read();
try {
len = await (randomAccess.length());
yield* _read();
} catch (E) {}
}
}
}
void tailAndPrint(File file) {
tail(file).transform(utf8.decoder).transform(LineSplitter()).forEach((line) {
// Do something with the line that has been read, e.g. print it out...
print(line);
});
try {
tail(file)
.transform(utf8.decoder)
.transform(LineSplitter())
.forEach((line) {
// Do something with the line that has been read, e.g. print it out...
print(line);
});
} catch (E) {}
}

View file

@ -1,124 +0,0 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'RconDecoder.dart';
abstract class RconClient {
void exit();
void send(String cmd);
factory RconClient() => RconClientImpl();
Stream<String> connect(String host, int port, String password);
}
class RconType {
/// RCON Packet Type 0: Server response
static const int SERVERDATA_RESPONSE_VALUE = 0;
/// RCON Packet Type 2: Server auth response
static const int SERVERDATA_AUTH_RESPONSE = 2;
/// RCON Packet Type 2: Client execute command
static const int SERVERDATA_EXECCOMMAND = 2;
/// RCON Packet Type 3: Client send authentication data
static const int SERVERDATA_AUTH = 3;
}
/// Client for the rcon protocol
class RconClientImpl implements RconClient {
/// Socket used to write and read TCP packets.
late Socket _socket;
/// Disconnect from the a RCON server.
///
/// Usage:
///
/// ```dart
/// RconClient client = RconClient.connect(print, 'localhost', '25575', 'password');
/// client.exit();
/// ```
@override
void exit() => _socket.destroy();
/// Send commands
@override
void send(String cmd) => _send(RconType.SERVERDATA_EXECCOMMAND, cmd);
/// Authenticate to the server
void _authenticate(String password) =>
_send(RconType.SERVERDATA_AUTH, password);
/// Build and send a packet to the rcon server
///
/// | Field | Type | Value |
/// |--------------|-------------------------------------|-------|
/// | Size | 32-bit little-endian Signed Integer | |
/// | ID | 32-bit little-endian Signed Integer | |
/// | Type | 32-bit little-endian Signed Integer | |
/// | Body | Null-terminated ASCII String | |
/// | Empty String | Null-terminated ASCII String | 0x00 |
void _send(int type, String payload) {
final Uint8List outSize = Uint8List(4);
final Uint8List outId = Uint8List(4); // Empty: 00 00 00 00
final Uint8List outType = Uint8List(4);
// Write type in the Type field
final ByteData typeData = ByteData.view(outType.buffer);
typeData.setInt32(0, type, Endian.little);
// Build the body
final List<int> outBody = utf8.encode(payload);
// Build ID + Type + Body + Empty String
final Uint8List outPacketBody =
Uint8List.fromList(outId + outType + outBody + Uint8List(2));
// Calculate the Size field
final ByteData sizeData = ByteData.view(outSize.buffer);
sizeData.setInt32(0, outPacketBody.length, Endian.little);
// Build the packet
final Uint8List packet = Uint8List.fromList(outSize + outPacketBody);
// View packet
// print(packet);
// print(packet.map((int i) => i.toRadixString(16)).toList());
// print(utf8.decode(packet));
// Send the packet
_socket.add(packet);
}
/// Connect to the a RCON server.
///
/// Usage:
///
/// ```dart
/// final RconClient client = RconClient();
/// final Stream<String> response = client.connect(
/// 'localhost',
/// 25575,
/// 'password',
/// );
/// ```
@override
Stream<String> connect(String host, int port, String password) async* {
print("Trying to connect...");
_socket = await Socket.connect(host, port);
print("Connected.");
final Stream<String> stream = _socket.transform(RconDecoder());
print("Trying to authenticate");
_authenticate(password);
yield* stream;
}
}

View file

@ -1,48 +0,0 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'Rcon.dart';
class RconDecoder extends Converter<Uint8List, String> {
/// Transform packets into a String.
///
/// | Field | Type | Value |
/// |--------------|-------------------------------------|-------|
/// | Size | 32-bit little-endian Signed Integer | |
/// | ID | 32-bit little-endian Signed Integer | |
/// | Type | 32-bit little-endian Signed Integer | |
/// | Body | Null-terminated ASCII String | |
/// | Empty String | Null-terminated ASCII String | 0x00 |
@override
String convert(Uint8List data) {
final byteData = ByteData.sublistView(data);
// final inLength = byteData.getInt32(0, Endian.little);
final inId = byteData.getInt32(4, Endian.little);
final inType = byteData.getInt32(8, Endian.little);
final inBody = data.sublist(12);
if (inType == RconType.SERVERDATA_AUTH_RESPONSE) {
if (inId == -1) {
throw const SocketException('Bad login.');
} else if (inId == 0) {
return 'Authentication successful. You can now write commands.';
}
}
return utf8.decode(inBody);
}
@override
Sink<Uint8List> startChunkedConversion(Sink<String> sink) {
return ChunkedConversionSink.withCallback((chunk) {
for (final data in chunk) {
sink.add(convert(data));
}
});
}
// Override the base class's bind, to provide a better type.
@override
Stream<String> bind(Stream<Uint8List> stream) => super.bind(stream);
}

View file

@ -1,6 +1,6 @@
name: libac_dart
description: "Aria's Creations code library"
version: 1.0.29
version: 1.0.31
homepage: "https://zontreck.com"