import 'dart:convert'; import 'package:dio/dio.dart'; import 'package:libac_dart/nbt/NbtUtils.dart'; import 'package:libac_dart/nbt/impl/CompoundTag.dart'; import 'package:libac_dart/nbt/impl/StringTag.dart'; import 'package:libac_dart/utils/Hashing.dart'; import 'package:zontreck/Packets.dart'; import 'package:zontreck/pages/OpenSim.dart'; enum APIEndpoint { SetupCheck(script: "SetupCheck.php", path: "/ac/home/supports/"), Ping(script: "Ping.php", path: "/ac/home/supports/"), Setup(script: "Setup.php", path: "/ac/home/supports/"), Register(script: "Register.php", path: "/ac/home/supports/"), Logout(script: "Logout.php", path: "/ac/home/supports/"), Login(script: "Login.php", path: "/ac/home/supports/"), ValidateSession(script: "ValidateToken.php", path: "/ac/home/supports/"), MakeFolder(script: "MakeFolder.php", path: "/ac/home/supports/"), ActivateUser(script: "ActivateUser.php", path: "/ac/home/supports/"); final String script; final String path; const APIEndpoint({required this.script, required this.path}); String getURL() { Settings settings = Settings(); return "${settings.API_SERVER}$path$script"; } } enum UserTitles { OPERATOR(title: "Grid Operator"), ADMIN(title: "Grid Admin"), USER(title: "Resident"); final String title; const UserTitles({required this.title}); } enum HTTPMethod { Get, Post, Put, Delete } class Settings { static Settings? _inst; Settings._(); Dio dio = Dio(); factory Settings() { if (Settings._inst != null) { return Settings._inst!; } else { Settings._inst = Settings._(); return Settings._inst!; } } static void Load(CompoundTag tag) {} static CompoundTag save() { CompoundTag tag = CompoundTag(); Settings settings = Settings(); NbtUtils.writeBoolean(tag, "loggedIn", settings.loggedIn); tag.put("name", StringTag.valueOf(settings.userName)); tag.put("display", StringTag.valueOf(settings.displayName)); if (settings.currentUser != null) { tag.put("user", settings.currentUser!.save()); } return tag; } String API_SERVER = ""; bool OpenSimSetupCompleted = false; String PSK = ""; // This is not saved anywhere it is discarded when the application is unloaded. bool loggedIn = false; String userName = ""; String displayName = ""; int totalGridUsers = 0; User? currentUser; bool get hasUsers => totalGridUsers != 0; bool get hasNoUsers => totalGridUsers == 0; void setServices(Map js) { var protocol = js['api']['protocol'] as String; var port = js['api']['port'] as int; var host = js['api']['host'] as String; API_SERVER = "$protocol://$host:$port/"; } Future hashPSK(String PSK) async { String hash = Hashing.md5Hash("AriasCreations"); for (int i = 0; i < 8192; i++) { hash = Hashing.sha256Hash("$hash:$PSK"); } hash = Hashing.sha256Hash(hash); return hash; } Future createDerivedPSK(String hashedPSK, String purpose) async { String hash = await hashPSK("$hashedPSK:$purpose"); return await hashPSK("$hash:$hashedPSK:$purpose"); // The derived PSK } Future sendPacketToEndpoint( APIEndpoint endpoint, IPacket packet) async { Response reply; switch (packet.method()) { case HTTPMethod.Post: { reply = await dio.post(endpoint.getURL(), data: packet.encode()); break; } case HTTPMethod.Get: { reply = await dio.get(endpoint.getURL()); break; } case HTTPMethod.Delete: { reply = await dio.delete(endpoint.getURL(), data: packet.encode()); break; } case HTTPMethod.Put: { reply = await dio.put(endpoint.getURL(), data: packet.encode()); break; } } return processResponsePacket(reply.data as String); } Future processResponsePacket(String reply) async { var tmpMap = json.decode(reply); String packetType = tmpMap['type'] as String; switch (packetType) { case "S2CSimpleReply": { S2CSimpleReplyPacket response = S2CSimpleReplyPacket.decode(reply); return response; } case "S2CPong": { S2CPongPacket pong = S2CPongPacket.decode(reply); return pong; } case "S2CLoginResponse": { S2CLoginResponsePacket response = S2CLoginResponsePacket.decode(reply); return response; } case "S2CSessionCheck": { S2CSessionCheckPacket response = S2CSessionCheckPacket.decode(reply); return response; } default: { return NullPacket(); } } } }