mirror of
https://github.com/chenasraf/mudblock.git
synced 2026-05-17 17:48:05 +00:00
feat: terminal type report
This commit is contained in:
@@ -396,6 +396,7 @@ class _GameButtonState extends State<GameButton> with GameStoreStateMixin {
|
||||
_callAction(data.longPressAction);
|
||||
setState(() {
|
||||
isClicking = false;
|
||||
isHovering = false;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -408,6 +409,7 @@ class _GameButtonState extends State<GameButton> with GameStoreStateMixin {
|
||||
void _onTapUp(TapUpDetails details) {
|
||||
setState(() {
|
||||
isClicking = false;
|
||||
isHovering = false;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -433,6 +435,8 @@ class _GameButtonState extends State<GameButton> with GameStoreStateMixin {
|
||||
_callCurrentDirection();
|
||||
setState(() {
|
||||
_direction = GameButtonInteraction.press;
|
||||
isHovering = false;
|
||||
isClicking = false;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -461,6 +465,7 @@ class _GameButtonState extends State<GameButton> with GameStoreStateMixin {
|
||||
|
||||
setState(() {
|
||||
isClicking = false;
|
||||
isHovering = false;
|
||||
_direction = GameButtonInteraction.press;
|
||||
_startDragTime = null;
|
||||
});
|
||||
|
||||
@@ -47,7 +47,7 @@ class GameStore extends ChangeNotifier {
|
||||
RegExp("(?<!$commandSeparator)$commandSeparator(?!$commandSeparator)");
|
||||
|
||||
MUDProfile get currentProfile => _currentProfile!;
|
||||
List<Alias> get aliases => currentProfile.aliases;
|
||||
List<Alias> get aliases => builtInAliases + (_currentProfile?.aliases ?? []);
|
||||
List<Trigger> get triggers => currentProfile.triggers;
|
||||
|
||||
get connected => _clientReady && _client.connected;
|
||||
@@ -93,7 +93,7 @@ class GameStore extends ChangeNotifier {
|
||||
onError: onError,
|
||||
);
|
||||
await currentProfile.load();
|
||||
echoSystem('Connecting...');
|
||||
echoSystem('Profile loaded. Connecting...');
|
||||
_client.connect();
|
||||
notifyListeners();
|
||||
}
|
||||
@@ -114,12 +114,6 @@ class GameStore extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
void requestMCCP() {
|
||||
debugPrint('requestMCCP');
|
||||
_client.doo(86);
|
||||
sendBytes([Symbols.iac, Symbols.doo, 86]);
|
||||
}
|
||||
|
||||
Future<void> disconnect() {
|
||||
return _client.disconnect();
|
||||
}
|
||||
@@ -129,7 +123,7 @@ class GameStore extends ChangeNotifier {
|
||||
}
|
||||
|
||||
void onRawData(List<int> bytes) {
|
||||
debugPrint('onRawData');
|
||||
debugPrint('Received Raw Data');
|
||||
try {
|
||||
final data = Message(bytes);
|
||||
handleSpecialMessages(data);
|
||||
@@ -148,14 +142,16 @@ class GameStore extends ChangeNotifier {
|
||||
}
|
||||
|
||||
void onData(Message data) {
|
||||
debugPrint('onData');
|
||||
try {
|
||||
if (currentProfile.mccpEnabled && isCompressed) {
|
||||
_rawStreamController.add(data.bytes);
|
||||
return;
|
||||
}
|
||||
debugPrint('onData: ${data.text}');
|
||||
debugPrint('Received data');
|
||||
handleSpecialMessages(data);
|
||||
if (isCompressed) {
|
||||
return;
|
||||
}
|
||||
if (data.text.isEmpty) {
|
||||
return;
|
||||
}
|
||||
@@ -170,56 +166,83 @@ class GameStore extends ChangeNotifier {
|
||||
}
|
||||
|
||||
void handleSpecialMessages(Message data) {
|
||||
final terminalSub = data.subnegotiation(24);
|
||||
if (data.isCommand) {
|
||||
debugPrint('Received command: ${data.bytes}');
|
||||
debugPrint('Received command: ${data.commands}');
|
||||
}
|
||||
final bytes = <int>[];
|
||||
if (data.doo(24)) {
|
||||
debugPrint('Received terminal type WILL request');
|
||||
sendBytes([Symbols.iac, Symbols.will, 24, Symbols.iac, Symbols.se]);
|
||||
} else if (data.sb(24) && data.bytes[3] == 1) {
|
||||
debugPrint('Received terminal type DO request');
|
||||
debugPrint('Sending terminal type WILL response');
|
||||
bytes.addAll([Symbols.iac, Symbols.will, 24]);
|
||||
}
|
||||
if (terminalSub != null &&
|
||||
terminalSub.isNotEmpty &&
|
||||
terminalSub.single == 1) {
|
||||
// } else if (terminalSub.isNotEmpty && terminalSub[0] == 1) {
|
||||
debugPrint('Received terminal type SEND request');
|
||||
final bytes = [
|
||||
final tt = const AsciiEncoder().convert('Mublock');
|
||||
final ttBytes = [
|
||||
Symbols.iac,
|
||||
Symbols.sb,
|
||||
24,
|
||||
0,
|
||||
...const AsciiEncoder().convert('Mublock'),
|
||||
...tt,
|
||||
Symbols.iac,
|
||||
Symbols.se
|
||||
];
|
||||
debugPrint('Sending terminal type: $bytes');
|
||||
sendBytes(bytes);
|
||||
} else if (!currentProfile.mccpEnabled) {
|
||||
return;
|
||||
bytes.addAll(ttBytes);
|
||||
debugPrint('Sending terminal type response: $ttBytes');
|
||||
}
|
||||
|
||||
// MCCP
|
||||
else {
|
||||
if (isCompressed) {
|
||||
if (data.se()) {
|
||||
disableMCCP();
|
||||
}
|
||||
} else {
|
||||
if (currentProfile.mccpEnabled) {
|
||||
if (!isCompressed) {
|
||||
if (data.sb(86)) {
|
||||
enableMCCP();
|
||||
debugPrint('Received compression start');
|
||||
if (bytes.isNotEmpty) {
|
||||
sendBytes(bytes);
|
||||
}
|
||||
enableCompression();
|
||||
// _rawStreamController.add(data.bytes);
|
||||
debugPrint(
|
||||
'bytes after mccp: ${data.bytes.sublist(data.bytes.indexOf(86) + 3)}');
|
||||
_rawStreamController
|
||||
.add(data.bytes.sublist(data.bytes.indexOf(86) + 3));
|
||||
echoSystem('Compression started');
|
||||
debugPrint("Done handling command (early)");
|
||||
return;
|
||||
} else if (data.will(86)) {
|
||||
requestMCCP();
|
||||
echo('Compression requested');
|
||||
debugPrint('Received compression request');
|
||||
bytes.addAll([Symbols.iac, Symbols.doo, 86]);
|
||||
debugPrint('Sending compression request');
|
||||
}
|
||||
} else { // isCompressed
|
||||
// if (data.se()) {
|
||||
// final seIndex = data.bytes.indexOf(Symbols.se);
|
||||
// if (data.bytes[seIndex - 1] == Symbols.iac) {
|
||||
// debugPrint('Received compression end');
|
||||
// disableCompression();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
sendBytes(bytes);
|
||||
debugPrint("Done handling command");
|
||||
// }
|
||||
}
|
||||
|
||||
void disableMCCP() {
|
||||
echo('Compression disabled');
|
||||
void disableCompression() {
|
||||
isCompressed = false;
|
||||
_decodedSub.cancel();
|
||||
echoSystem('Compression disabled');
|
||||
}
|
||||
|
||||
void enableMCCP() {
|
||||
void enableCompression() {
|
||||
isCompressed = true;
|
||||
_decodedStream = _decoder.decoder.bind(_rawStreamController.stream);
|
||||
_decodedSub = _decodedStream.listen(onRawData);
|
||||
echo('Compression enabled');
|
||||
echoSystem('Compression enabled');
|
||||
}
|
||||
|
||||
void onError(Object error) {
|
||||
@@ -462,8 +485,7 @@ class GameStore extends ChangeNotifier {
|
||||
}
|
||||
|
||||
mixin GameStoreMixin {
|
||||
GameStore storeOf(BuildContext context) =>
|
||||
GameStore.of(context);
|
||||
GameStore storeOf(BuildContext context) => GameStore.of(context);
|
||||
}
|
||||
|
||||
mixin GameStoreStateMixin<T extends StatefulWidget> on State<T> {
|
||||
|
||||
@@ -17,6 +17,8 @@ void main() async {
|
||||
|
||||
final w = prefs.getInt('windowWidth') ?? 1000;
|
||||
final h = prefs.getInt('windowHeight') ?? 900;
|
||||
// final x = prefs.getInt('windowX') ?? 0;
|
||||
// final y = prefs.getInt('windowY') ?? 0;
|
||||
final size = Size(w.toDouble(), h.toDouble());
|
||||
|
||||
WindowOptions windowOptions = WindowOptions(
|
||||
|
||||
@@ -168,6 +168,20 @@ class HomePageState extends State<HomePage>
|
||||
store.selectInput();
|
||||
}
|
||||
|
||||
@override
|
||||
void onWindowMove() {
|
||||
EasyDebounce.debounce(
|
||||
'windowMove',
|
||||
const Duration(milliseconds: 500),
|
||||
() async {
|
||||
final position = await windowManager.getPosition();
|
||||
debugPrint("Window moved to $position");
|
||||
prefs.setInt('windowX', position.dx.toInt());
|
||||
prefs.setInt('windowY', position.dy.toInt());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void onWindowResize() async {
|
||||
EasyDebounce.debounce(
|
||||
|
||||
@@ -100,11 +100,10 @@ packages:
|
||||
ctelnet:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: ctelnet
|
||||
sha256: "06cba141577de338adc9436ad733f33668224b0cfcf046f8edd58fcde09aeed2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.4"
|
||||
path: "../ctelnet"
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.1.5"
|
||||
cupertino_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
||||
@@ -28,7 +28,9 @@ environment:
|
||||
# the latest version available on pub.dev. To see which dependencies have newer
|
||||
# versions available, run `flutter pub outdated`.
|
||||
dependencies:
|
||||
ctelnet: ^0.1.4
|
||||
# ctelnet: ^0.1.4
|
||||
ctelnet:
|
||||
path: ../ctelnet
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
|
||||
Reference in New Issue
Block a user