From bf7aaa2a5611eff7371ab32f2cc7299355449e64 Mon Sep 17 00:00:00 2001 From: squid Date: Fri, 23 May 2025 14:24:44 +0200 Subject: [PATCH] docs(README.md): deprecate Prima project and redirect users to Moongate for latest updates and features feat(LoginCompleteHandler.cs): enable network compression for session to improve performance refactor(NetworkService.cs): update logging message to use packetContent instead of data feat(src.sln): add Visual Studio solution file for the project --- README.md | 275 ++---------------- .../Handlers/LoginCompleteHandler.cs | 5 +- src/Prima.Server/Services/NetworkService.cs | 4 +- src/src.sln | 54 ++++ 4 files changed, 80 insertions(+), 258 deletions(-) create mode 100644 src/src.sln diff --git a/README.md b/README.md index 65b518a..4080f8e 100644 --- a/README.md +++ b/README.md @@ -1,270 +1,35 @@ -# PrimaUO Server +# 🚨 DEPRECATED – Prima -![Docker Image Version (tag)](https://img.shields.io/docker/v/tgiachi/prima-server/latest) -[![GitHub Actions](https://github.com/tgiachi/prima/actions/workflows/docker_image.yml/badge.svg)](https://github.com/tgiachi/prima/actions/workflows/docker_image.yml) -[![License](https://img.shields.io/badge/license-MIT-red.svg)](LICENSE) +**This repository is no longer maintained.** +The Prima project has been deprecated and completely rewritten as part of the [Moongate](https://github.com/Moongate-server/Moongate) initiative. -![](./Assets/prima_logo.png) +--- -PrimaUO is a modern Ultima Online server implementation written in C# (.NET 9.0). The project aims to provide a modern, extensible, and maintainable server alternative with support for the latest client versions. +## ❗️ Important Notice -## Features +This project is archived and will not receive further updates or support. +For the latest development, please refer to the new project: -- ⚑ Modern C# (.NET 9.0) implementation -- πŸ”„ Event-driven architecture -- πŸš€ High performance through optimized code and event loop system -- πŸ”Œ Modular design with dependency injection -- πŸ“¦ Support for multiple client versions -- πŸ”’ Secure authentication using JWT -- πŸ“ˆ Built-in metrics and diagnostics -- πŸ”§ Extensible through JavaScript scripting system -- 🌐 REST API for integration with external tools -- 🌍 Multi-language support with localization services -- πŸ’Ύ Automatic world saving system -- 🧰 Modern UOP file format support +πŸ‘‰ [Moongate](https://github.com/Moongate-server/Moongate) -## Scripting System +--- -PrimaUO includes a powerful JavaScript scripting engine that allows you to extend and customize server functionality without modifying the core code. Scripts are loaded from the `scripts` directory and can interact with server systems through registered modules. +## Why the Change? -### Example Script +Prima served as an initial prototype for my solution. However, to address architectural limitations and enhance scalability, I have restructured and rebuilt the project from the ground up under the Moongate initiative. -```javascript -// bootstrap.js -// This script is executed when the server starts +--- -// Import script modules are automatically registered by the server -// Log a message to the server console -console.Log("Server startup script loaded!"); +## What’s New in Moongate? -// Listen for server started event -events.OnStarted(() => { - logger.Info("Server has started successfully!"); +- **Modernized architecture** with improved performance +- **Enhanced developer experience** and documentation +- **Active development and community support** - // Register admin commands - commands.RegisterConsoleCommand( - "announce", - "Broadcasts a message to all players", - (args) => { - const message = args.join(" "); - logger.Info(`Broadcasting message: ${message}`); - // Actual broadcast implementation would go here - return true; - }, - ["broadcast", "shout"], - CommandType.ALL, - CommandPermissionType.ADMIN - ); +--- - // Create a recurring task to run every 5 minutes - scheduler.ScheduleTask( - "cleanup", - 300, // seconds - () => { - logger.Info("Running scheduled cleanup task..."); - // Cleanup logic would go here - } - ); +## Migration - // Register an event handler for character creation - events.OnCharacterCreated((args) => { - logger.Info(`New character created: ${args.Name}`); +We encourage all users and contributors to transition to [Moongate](https://github.com/Moongate-server/Moongate) for the latest updates and features. - // Start a delayed welcome timer - timers.OneShot("welcome_message", 10, () => { - logger.Info(`Sending welcome message to ${args.Name}`); - // Actual welcome message code would go here - }); - }); - - // Register custom item - items.Register("enchanted_sword", { - ItemId: 3937, - Name: "Enchanted Longsword", - GraphicId: 0x0F60, - Weight: 4.0, - Layer: Layer.ONE_HANDED, - Amount: 1, - Damage: { - Min: 10, - Max: 25, - Type: "Slashing" - } - }); -}); -``` - -### Available Script Modules - -The scripting API exposes the following modules: - -- **logger**: Functions for logging at different levels (Info, Debug, Warn, Error, Critical) -- **events**: Subscribe to server events like OnStarted, OnUserLogin, OnCharacterCreated -- **scheduler**: Schedule tasks to run periodically -- **template**: Add variables for template rendering and text processing -- **files**: Include other script files or directories -- **timers**: Create one-time or repeating timers with delays -- **items**: Register custom items with properties and behaviors -- **console**: Log messages to the console or prompt for input -- **commands**: Register custom commands for console or in-game use - -## Project Structure - -- **Prima.Core.Server**: Core server infrastructure -- **Prima.Network**: Network layer and packet handling -- **Prima.Server**: Main server application -- **Prima.UOData**: Ultima Online data structures and utilities -- **Prima.JavaScript.Engine**: JavaScript scripting engine for server extensibility -- **Prima.Tcp.Test**: TCP testing utilities - -## Getting Started - -### Prerequisites - -- .NET 9.0 SDK -- Ultima Online client files for data loading - -### Configuration - -Configuration is handled through YAML files located in the `configs` directory. Here's an example configuration: - -```yaml -debug: - save_raw_packets: false -process: - pid_file: server.pid - process_queue: - max_parallel_task: 2 -shard: - max_players: 1000 - uo_directory: /path/to/uo/files - client_version: - name: Prima Shard - admin_email: admin@primauo.com - url: https://github.com/tgiachi/prima - time_zone: 0 - language: en - autosave: - interval_in_minutes: 5 -jwt_auth: - issuer: Prima - audience: Prima - secret: YourSecretKey - expiration_in_minutes: 44640 - refresh_token_expiry_days: 1 -accounts: - is_registration_enabled: true -smtp: - host: localhost - port: 25 - username: '' - password: '' - use_ssl: false - use_start_tls: false -tcp_server: - host: '' - login_port: 2593 - game_port: 2592 - enable_web_server: true - web_server_port: 23000 - log_packets: true -``` - -### Building from Source - -```bash -git clone https://github.com/tgiachi/prima.git -cd prima -dotnet build -``` - -### Running the Server - -```bash -cd src/Prima.Server -dotnet run -``` - -### Docker Support - -A Dockerfile is provided to build and run the server in a container: - -```bash -docker build -t primauo/server . -docker run -p 2593:2593 -p 2592:2592 -p 23000:23000 -v /path/to/uo/files:/app/data/client primauo/server -``` - -## API Documentation - -The server includes a Swagger UI for API documentation available at: - -``` -http://localhost:23000/swagger -``` - -## Type Definitions for Scripts - -The server automatically generates TypeScript definitions for the scripting API in `scripts/index.d.ts`, which provides autocomplete and type checking when using an editor like Visual Studio Code: - -```typescript -/** - * prima v0.15.4.0 JavaScript API TypeScript Definitions - * Auto-generated documentation on 2025-05-16 10:46:15 - **/ - -// Constants -declare const APP_NAME: string; -declare const VERSION: string; - -// Modules -declare const logger: { - Info(Message: string, Args: any[]): void; - Warn(Message: string, Args: any[]): void; - Error(Message: string, Args: any[]): void; - Critical(Message: string, Args: any[]): void; - Debug(Message: string, Args: any[]): void; -}; - -declare const events: { - OnStarted(Action: () => void): void; - HookEvent(EventName: string, EventHandler: (arg: any) => void): void; - OnUserLogin(Action: (arg: IUserLoginContext) => void): void; - OnCharacterCreated(Action: (arg: ICharacterCreatedEventArgs) => void): void; -}; - -// ... and other module definitions -``` - -### Help Wanted! -I'm actively seeking developers to join the PrimaUO project! -This project aims to modernize Ultima Online and keep this legendary MMORPG alive for future generations. Whether you're skilled in C#, JavaScript, network programming, or game development, your contributions can make a difference. -Why join us: - -Work on preserving gaming history -Modernize a classic MMORPG with cutting-edge technologies -Join a passionate community of UO enthusiasts -Gain experience with .NET 9.0, modern architecture patterns, and game server development - -No previous Ultima Online development experience is required - just enthusiasm and a willingness to learn. If you're interested in contributing, please reach out via GitHub issues or discussions. -Together, we can ensure Ultima Online continues to thrive for years to come! - - -## Contributing - -Contributions are welcome! Please feel free to submit a Pull Request. - -1. Fork the repository -2. Create your feature branch (`git checkout -b feature/amazing-feature`) -3. Commit your changes (`git commit -m 'Add some amazing feature'`) -4. Push to the branch (`git push origin feature/amazing-feature`) -5. Open a Pull Request - -## License - -This project is licensed under the MIT License - see the LICENSE file for details. - -## Acknowledgments - -- The Ultima Online community -- [ModernUO](https://github.com/modernuo/modernuo) for inspiration and some utility code -- [UOX3](https://github.com/UOX3DevTeam/UOX3) for inspiration +Thank you for your support and contributions to Prima! diff --git a/src/Prima.Server/Handlers/LoginCompleteHandler.cs b/src/Prima.Server/Handlers/LoginCompleteHandler.cs index 672100f..d63d5f4 100644 --- a/src/Prima.Server/Handlers/LoginCompleteHandler.cs +++ b/src/Prima.Server/Handlers/LoginCompleteHandler.cs @@ -26,12 +26,15 @@ protected override void RegisterHandlers() public async Task HandleAsync(LoginCompleteEvent @event, CancellationToken cancellationToken = default) { + var session = SessionService.GetSession(@event.SessionId); + session.UseNetworkCompression = true; + var mobile = session.GetProperty(); // Login confirmation packet await session.SendPacketAsync(new CharLocaleAndBody(mobile)); - // GeneralInformation packet + //GeneralInformation packet await session.SendPacketAsync(new SeasonalInformation(Season.Spring, true)); await session.SendPacketAsync(new DrawGamePlayer(mobile)); await session.SendPacketAsync(new CharacterDraw(mobile)); diff --git a/src/Prima.Server/Services/NetworkService.cs b/src/Prima.Server/Services/NetworkService.cs index f45297a..f3c1414 100644 --- a/src/Prima.Server/Services/NetworkService.cs +++ b/src/Prima.Server/Services/NetworkService.cs @@ -231,8 +231,8 @@ private async Task SendPacketInternal(string sessionId, IUoNetworkPacket packet) "-> {PacketType} {Session} ({Size} bytes) {Data}", packet.GetType().Name, sessionId.ToShortSessionId(), - data.Length, - data.ToArray().HumanizedContent(20) + packetContent.Length, + packetContent.HumanizedContent(20) ); await _networkTransportManager.EnqueueMessageAsync( diff --git a/src/src.sln b/src/src.sln new file mode 100644 index 0000000..93685b7 --- /dev/null +++ b/src/src.sln @@ -0,0 +1,54 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prima.Tcp.Test", "Prima.Tcp.Test\Prima.Tcp.Test.csproj", "{F80C9EA4-41E1-D42F-AEF0-B836341FE624}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prima.UOData", "Prima.UOData\Prima.UOData.csproj", "{CB0AD729-B3AA-65AC-7F42-D703FAAB4949}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prima.Server", "Prima.Server\Prima.Server.csproj", "{F6BFD976-8F6F-7B94-82F7-4D8C1829417E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prima.Core.Server", "Prima.Core.Server\Prima.Core.Server.csproj", "{E6D09843-A464-8604-1143-2E6DA21DBE55}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prima.Network", "Prima.Network\Prima.Network.csproj", "{D784E30C-1DE7-057A-DD71-1E2FE32F523D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prima.JavaScript.Engine", "Prima.JavaScript.Engine\Prima.JavaScript.Engine.csproj", "{8D77D0F0-24E3-CCDA-F5D8-4BD39E23ED64}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F80C9EA4-41E1-D42F-AEF0-B836341FE624}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F80C9EA4-41E1-D42F-AEF0-B836341FE624}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F80C9EA4-41E1-D42F-AEF0-B836341FE624}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F80C9EA4-41E1-D42F-AEF0-B836341FE624}.Release|Any CPU.Build.0 = Release|Any CPU + {CB0AD729-B3AA-65AC-7F42-D703FAAB4949}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB0AD729-B3AA-65AC-7F42-D703FAAB4949}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB0AD729-B3AA-65AC-7F42-D703FAAB4949}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB0AD729-B3AA-65AC-7F42-D703FAAB4949}.Release|Any CPU.Build.0 = Release|Any CPU + {F6BFD976-8F6F-7B94-82F7-4D8C1829417E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6BFD976-8F6F-7B94-82F7-4D8C1829417E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6BFD976-8F6F-7B94-82F7-4D8C1829417E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6BFD976-8F6F-7B94-82F7-4D8C1829417E}.Release|Any CPU.Build.0 = Release|Any CPU + {E6D09843-A464-8604-1143-2E6DA21DBE55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E6D09843-A464-8604-1143-2E6DA21DBE55}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E6D09843-A464-8604-1143-2E6DA21DBE55}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E6D09843-A464-8604-1143-2E6DA21DBE55}.Release|Any CPU.Build.0 = Release|Any CPU + {D784E30C-1DE7-057A-DD71-1E2FE32F523D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D784E30C-1DE7-057A-DD71-1E2FE32F523D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D784E30C-1DE7-057A-DD71-1E2FE32F523D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D784E30C-1DE7-057A-DD71-1E2FE32F523D}.Release|Any CPU.Build.0 = Release|Any CPU + {8D77D0F0-24E3-CCDA-F5D8-4BD39E23ED64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D77D0F0-24E3-CCDA-F5D8-4BD39E23ED64}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D77D0F0-24E3-CCDA-F5D8-4BD39E23ED64}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D77D0F0-24E3-CCDA-F5D8-4BD39E23ED64}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DBC843DA-943B-4F27-87DB-4BD5E473D031} + EndGlobalSection +EndGlobal