A powerful, multi-purpose C# server built with a modern, service-oriented architecture. Features real-time dashboard, robust user management, a dynamic plugin system, and secure video streaming capabilities. Designed for game servers, monitoring systems, and real-time applications.
Check out the live dashboard here: Live Dashboard
- Features
- Requirements
- Installation
- Plugin Development Tutorial
- Running it
- Usage
- API Endpoints
- Configuration
- Video Management
- Logging
- Security Features
- Troubleshooting
- License
- Contributing
- Support
- Service-Oriented Design: Decoupled services for improved maintainability and testability.
- Dependency Injection: Clean, modular code with clear separation of concerns.
- Asynchronous Performance: Full
async/await
implementation for high concurrency and non-blocking I/O. - Event-Driven Communication: A robust in-memory Event Bus for decoupled, scalable inter-service communication.
- Advanced Password Hashing: Securely hashes passwords using PBKDF2 with unique salts.
- Account Lockout Policy: Automatically locks accounts after multiple failed login attempts.
- JWT & Refresh Tokens: Secure, stateless authentication with short-lived access tokens and long-lived refresh tokens.
- Comprehensive Input Validation: Protects against injection attacks and malicious data.
- Strong Password Policies: Enforces configurable password complexity requirements.
- In-Memory Caching: Reduces database/file I/O for frequently accessed data.
- HTTP Response Compression: Automatically compresses responses to save bandwidth.
- Connection Pooling Framework: Efficiently manages and reuses network connections.
- Graceful Shutdown: Ensures data is saved and connections close properly on exit.
- Modern, responsive dark-themed interface
- Real-time system monitoring (CPU, memory, disk, network)
- Live server logs viewer with color-coded levels
- Video player with streaming support and progress tracking
- Secure user authentication with JWT tokens
- Mobile-friendly design
- Secure user registration and login system
- Role-based access control (RBAC)
- Session management with "remember me" functionality
- Password reset functionality via email token
- Two-Factor Authentication (2FA) support framework
- Real-time CPU usage tracking
- Memory consumption monitoring
- Disk space usage information
- Network traffic statistics
- Historical performance charts
- Upload videos from URLs with progress tracking
- Stream videos directly in the dashboard
- Support for multiple video formats (MP4, WebM, OGG, AVI, MOV, MKV)
- Video library with thumbnail previews
- Secure access control for all video content
- Hot-Reloading: Load, update, and unload plugins at runtime without restarting the server.
- Sandboxed Execution: Plugins run in isolated contexts for security and stability.
- Async Lifecycle Hooks: Plugins can hook into server events with
OnLoadAsync
,OnUpdateAsync
, andOnUnloadAsync
. - Easy Development: Simple C# interface-based development model for extending server functionality.
- .NET 6.0 SDK or Runtime
- Windows, Linux, or Docker-compatible environment
- Ports open for TCP connections (default:
11001
for server,11002
for web dashboard) - Modern web browser with JavaScript enabled
- Clone the repository:
git clone https://github.com/VoidbornGames/Ultimate_C_Sharp_Server.git cd Ultimate_C_Sharp_Server
- Build the project:
dotnet build
UltimateServer's functionality can be easily extended using a powerful plugin system. This tutorial will guide you through creating your first plugin.
A plugin is a separate .NET assembly (a .dll file) that contains code to extend the server's features. The server automatically loads these assemblies from a designated directory, allowing you to add new commands, integrate with other services, or react to server events without modifying the core server code.
- .NET 6.0 SDK
- A C# IDE like Visual Studio 2022, VS Code, or JetBrains Rider.
- A copy of the UltimateServer source code.
First, create a new project for your plugin. Open your terminal or command prompt and run:
dotnet new classlib -n MyAwesomePlugin
cd MyAwesomePlugin
This will create a new C# class library project named MyAwesomePlugin
.
Your plugin needs to know about the IPlugin
interface. You can do this by adding a project reference to the UltimateServer project.
dotnet add reference ../path/to/UltimateServer/Server.csproj
Note: Replace ../path/to/UltimateServer/
with the actual relative path to the server project file. It's good practice to copy the IPlugin.cs
and PluginContext.cs
files into your plugin project instead of referencing the whole server project to keep your plugin independent.
Now, rename the default Class1.cs
to something more descriptive, like MainPlugin.cs
. Open the file and implement the IPlugin
interface.
Here is a complete example of a simple plugin:
using System; using System.Threading.Tasks; using UltimateServer.Plugins;
namespace MyAwesomePlugin { public class MainPlugin : IPlugin { // A unique name for your plugin public string Name => "My Awesome Plugin";
// The version of your plugin public string Version => "1.0.0"; // This method is called when the plugin is first loaded by the server. public async Task OnLoadAsync(PluginContext context) { context.Logger.Log("Hello from My Awesome Plugin! I have been loaded."); // You can initialize resources, register commands, etc. here. await Task.CompletedTask; } // This method is called when the server's plugin manager performs an update. // Useful for reloading configuration or applying hot-fixes. public async Task OnUpdateAsync(PluginContext context) { context.Logger.Log("My Awesome Plugin has been updated."); await Task.CompletedTask; } // This method is called when the plugin is being unloaded (e.g., during shutdown or hot-reload). public async Task OnUnloadAsync(PluginContext context) { context.Logger.Log("Goodbye! My Awesome Plugin is unloading."); // You should dispose of any resources here. await Task.CompletedTask; } }
}
From inside your plugin's directory (MyAwesomePlugin
), run the build command:
dotnet build -c Release
This will compile your code and produce a MyAwesomePlugin.dll
file inside the bin/Release/net6.0/
directory.
- Navigate to your UltimateServer's root directory.
- Create a new folder named
plugins
if it doesn't already exist. - Copy your plugin's
.dll
file (e.g.,MyAwesomePlugin.dll
) into theplugins
folder.
That's it! Now, simply run the UltimateServer. You will see your plugin's log message in the console when it starts up.
dotnet Server.dll 11001 11002
Output:
...
π Scanning for plugins in '.../UltimateServer/plugins'
π Found valid assembly: MyAwesomePlugin, Version=1.0.0.0
β
Loaded plugin: My Awesome Plugin v1.0.0
Hello from My Awesome Plugin! I have been loaded.
π Plugin loading complete. 1 plugins loaded.
...
You can now update your plugin's code, rebuild it, copy the new .dll
to the plugins
folder, and the server will automatically reload it without needing a restart!
dotnet Server.dll 11001 11002
dotnet Server.dll <Server_Port> <Dashboard_Port>
docker build -t ultimateserver .
docker run -p 11001:11001 -p 11002:11002 ultimateserver
- Open your web browser and navigate to:
http://your-server-ip:11002
- Login with the default credentials:
- Username:
admin
- Password:
admin123
- Username:
- Explore the dashboard features:
- Stats: View real-time system performance
- Logs: Monitor server activity
- Videos: Upload and stream videos
The server supports several built-in commands that can be sent via TCP:
createUser
: Create a new user accountloginUser
: Authenticate a userlistUsers
: Get a list of all userssay
: Echo a message back to the clientmakeUUID
: Generate a unique identifierstats
: Get server statistics
POST /api/login
: Authenticate user and get JWT token{ "username": "admin", "password": "admin123", "rememberMe": true }
POST /api/register
: Register a new user{ "username": "newuser", "email": "user@example.com", "password": "StrongPassword123!", "role": "player" }
POST /api/refresh-token
: Get a new access token using a refresh tokenPOST /api/logout
: Invalidate the user's refresh token
GET /stats
: Get basic server statistics (requires authentication)GET /system
: Get detailed system performance data (requires authentication)GET /logs
: Get recent server logs (requires authentication)
POST /api/plugins/reload
: Triggers a scan and reload of all plugins in the plugins directory (requires authentication).
GET /videos
: List all available videos (requires authentication)POST /upload-url
: Upload a video from a URL (requires authentication)GET /videos/{filename}
: Stream a video file (requires authentication)
All protected endpoints require a valid JWT token in the Authorization header:
Authorization: Bearer <your-jwt-token>
The server uses a config.json
file for configuration:
{
"Ip": "0.0.0.0",
"MaxConnections": 50,
"PasswordMinLength": 8,
"RequireSpecialChars": true,
"MaxFailedLoginAttempts": 5,
"LockoutDurationMinutes": 30,
"JwtExpiryHours": 24,
"RefreshTokenDays": 7,
"MaxRequestSizeMB": 100,
"EnableCompression": true,
"CacheExpiryMinutes": 15,
"ConnectionPoolSize": 10,
"PluginsDirectory": "plugins"
}
- Ip: Server IP address to bind to (default: "0.0.0.0")
- MaxConnections: Maximum number of concurrent connections (default: 50)
- PasswordMinLength: Minimum required length for user passwords.
- RequireSpecialChars: Enforces special characters in passwords.
- MaxFailedLoginAttempts: Number of failed attempts before account lockout.
- LockoutDurationMinutes: Duration of the account lockout.
- JwtExpiryHours: Expiration time for JWT access tokens.
- RefreshTokenDays: Expiration time for refresh tokens.
- EnableCompression: Enables Gzip/Deflate compression for HTTP responses.
- CacheExpiryMinutes: Default expiry time for cached items.
- ConnectionPoolSize: The number of connections to keep in the pool.
- PluginsDirectory: The directory where the server scans for plugin DLLs (default: "plugins").
- Navigate to the Videos tab in the dashboard
- Enter a video URL in the upload field
- Click Download to upload the video to the server
- The video will appear in your video library
- MP4 (video/mp4)
- WebM (video/webm)
- OGG (video/ogg)
- AVI (video/x-msvideo)
- MOV (video/quicktime)
- MKV (video/x-matroska)
Videos are streamed directly from the server with support for:
- Range requests for efficient streaming
- Proper MIME type handling
- Authentication protection
- Progress tracking during upload
The server maintains detailed logs in the logs/
directory:
- Log Rotation: Logs are automatically rotated and compressed when the server restarts
- Log Levels: Information, warnings, errors, and security events are logged with timestamps
- Real-time Viewing: View live logs in the dashboard without needing to access the server files
Log files are named with timestamps:
logs/latest_2025-10-01_23-30-45.zip
- PBKDF2 Password Hashing: User passwords are securely hashed with a unique salt.
- Account Lockout: Protects against brute-force attacks.
- JWT & Refresh Token Authentication: Secure, stateless session management.
- Input Validation: All inputs are validated to prevent injection attacks.
- File Access Control: Video files are protected with authentication checks.
- CORS Support: Properly configured Cross-Origin Resource Sharing headers.
If the server fails to start, it's often due to a dependency injection configuration error.
- Check Logs: The console output will show the exact error message, such as "Unable to resolve service for type 'System.String'".
- Verify Packages: Ensure the
Microsoft.Extensions.DependencyInjection
NuGet package is installed. - Check Program.cs: Make sure all services (like `FilePaths`, `ServerSettings`) are registered in the DI container.
- Check that the video file exists on the server
- Verify the video format is supported
- Check browser console for error messages
- Ensure your authentication token is valid
- Verify the default credentials: admin/admin123
- Check that your browser allows cookies
- Clear browser cache and try again
- Check server logs for authentication errors
- Monitor CPU and memory usage in the dashboard
- Check the number of active connections
- Review logs for any error messages
- Consider increasing
MaxConnections
orConnectionPoolSize
if needed
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the project
- Create your feature branch (
git checkout -b feature/AmazingFeature
) - Commit your changes (
git commit -m 'Add some AmazingFeature'
) - Push to the branch (
git push origin feature/AmazingFeature
) - Open a Pull Request