Sync from GitHub main #1
@@ -0,0 +1,51 @@
|
||||
name: Publish Host (Avalonia)
|
||||
|
||||
# Produces self-contained, single-file Server Host binaries for Windows and
|
||||
# Linux. No .NET runtime is required on the target machine. Runs on demand and
|
||||
# on version tags; each build is uploaded as a workflow artifact.
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags:
|
||||
- "host-v*"
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Publish ${{ matrix.rid }}
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
rid: [win-x64, linux-x64]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-dotnet@v4
|
||||
# The runner user cannot write to system /usr/share/dotnet; install the
|
||||
# pinned SDK into a runner-writable, cached path instead.
|
||||
env:
|
||||
DOTNET_INSTALL_DIR: ${{ runner.tool_cache }}/dotnet
|
||||
with:
|
||||
dotnet-version: "8.0.x"
|
||||
|
||||
- name: Publish single-file self-contained
|
||||
# Untrimmed on purpose: the host uses reflection-based Avalonia bindings,
|
||||
# which the trimmer would strip.
|
||||
run: >
|
||||
dotnet publish host/CommonwealthOnline.Host.csproj
|
||||
-c Release
|
||||
-r ${{ matrix.rid }}
|
||||
--self-contained true
|
||||
-p:PublishSingleFile=true
|
||||
-p:IncludeNativeLibrariesForSelfExtract=true
|
||||
-p:DebugType=none
|
||||
-o out/${{ matrix.rid }}
|
||||
--nologo
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CommonwealthOnline.Host-${{ matrix.rid }}
|
||||
path: out/${{ matrix.rid }}/
|
||||
if-no-files-found: error
|
||||
+195
-7
@@ -3,23 +3,211 @@
|
||||
x:Class="CommonwealthOnline.Host.App"
|
||||
RequestedThemeVariant="Dark">
|
||||
|
||||
<Application.Styles>
|
||||
<FluentTheme />
|
||||
</Application.Styles>
|
||||
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<Color x:Key="CoBackground">#0E120B</Color>
|
||||
<Color x:Key="CoSurface">#171C10</Color>
|
||||
|
||||
<!-- ============ Palette ============ -->
|
||||
<Color x:Key="CoBackground">#0A0E07</Color>
|
||||
<Color x:Key="CoBackgroundTop">#12180C</Color>
|
||||
<Color x:Key="CoSurface">#151B0F</Color>
|
||||
<Color x:Key="CoSurface2">#1C2314</Color>
|
||||
<Color x:Key="CoSurface3">#232C18</Color>
|
||||
<Color x:Key="CoBorder">#2C3720</Color>
|
||||
<Color x:Key="CoBorderBright">#43532F</Color>
|
||||
<Color x:Key="CoAccent">#E6D28C</Color>
|
||||
<Color x:Key="CoAccentBright">#F6ECBE</Color>
|
||||
<Color x:Key="CoText">#D8D2BE</Color>
|
||||
<Color x:Key="CoDanger">#C24B4B</Color>
|
||||
<Color x:Key="CoMuted">#8A9068</Color>
|
||||
<Color x:Key="CoGreen">#8BD05C</Color>
|
||||
<Color x:Key="CoGreenDim">#3E5C28</Color>
|
||||
<Color x:Key="CoDanger">#C85450</Color>
|
||||
<Color x:Key="CoDangerDim">#5A2A28</Color>
|
||||
|
||||
<SolidColorBrush x:Key="CoBackgroundBrush" Color="{StaticResource CoBackground}" />
|
||||
<SolidColorBrush x:Key="CoSurfaceBrush" Color="{StaticResource CoSurface}" />
|
||||
<SolidColorBrush x:Key="CoSurface2Brush" Color="{StaticResource CoSurface2}" />
|
||||
<SolidColorBrush x:Key="CoSurface3Brush" Color="{StaticResource CoSurface3}" />
|
||||
<SolidColorBrush x:Key="CoBorderBrush" Color="{StaticResource CoBorder}" />
|
||||
<SolidColorBrush x:Key="CoBorderBrightBrush" Color="{StaticResource CoBorderBright}" />
|
||||
<SolidColorBrush x:Key="CoAccentBrush" Color="{StaticResource CoAccent}" />
|
||||
<SolidColorBrush x:Key="CoAccentBrightBrush" Color="{StaticResource CoAccentBright}" />
|
||||
<SolidColorBrush x:Key="CoTextBrush" Color="{StaticResource CoText}" />
|
||||
<SolidColorBrush x:Key="CoMutedBrush" Color="{StaticResource CoMuted}" />
|
||||
<SolidColorBrush x:Key="CoGreenBrush" Color="{StaticResource CoGreen}" />
|
||||
<SolidColorBrush x:Key="CoDangerBrush" Color="{StaticResource CoDanger}" />
|
||||
|
||||
<!-- ============ Gradients ============ -->
|
||||
<LinearGradientBrush x:Key="CoWindowBrush" StartPoint="0%,0%" EndPoint="0%,100%">
|
||||
<GradientStop Offset="0" Color="{StaticResource CoBackgroundTop}" />
|
||||
<GradientStop Offset="1" Color="{StaticResource CoBackground}" />
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="CoBarBrush" StartPoint="0%,0%" EndPoint="0%,100%">
|
||||
<GradientStop Offset="0" Color="#1B2212" />
|
||||
<GradientStop Offset="1" Color="#12180C" />
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="CoAccentButtonBrush" StartPoint="0%,0%" EndPoint="0%,100%">
|
||||
<GradientStop Offset="0" Color="#F0DC9C" />
|
||||
<GradientStop Offset="1" Color="#D8C079" />
|
||||
</LinearGradientBrush>
|
||||
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
|
||||
<Application.Styles>
|
||||
<FluentTheme />
|
||||
|
||||
<!-- Section header label -->
|
||||
<Style Selector="TextBlock.section">
|
||||
<Setter Property="Foreground" Value="{StaticResource CoAccentBrush}" />
|
||||
<Setter Property="FontWeight" Value="Bold" />
|
||||
<Setter Property="FontSize" Value="12" />
|
||||
<Setter Property="LetterSpacing" Value="2" />
|
||||
</Style>
|
||||
|
||||
<!-- Small muted field label -->
|
||||
<Style Selector="TextBlock.fieldlabel">
|
||||
<Setter Property="Foreground" Value="{StaticResource CoMutedBrush}" />
|
||||
<Setter Property="FontSize" Value="11" />
|
||||
<Setter Property="LetterSpacing" Value="1" />
|
||||
<Setter Property="Margin" Value="2,0,0,3" />
|
||||
</Style>
|
||||
|
||||
<!-- Text inputs -->
|
||||
<Style Selector="TextBox">
|
||||
<Setter Property="Background" Value="{StaticResource CoSurface2Brush}" />
|
||||
<Setter Property="Foreground" Value="{StaticResource CoTextBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource CoBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="5" />
|
||||
<Setter Property="CaretBrush" Value="{StaticResource CoAccentBrush}" />
|
||||
<Setter Property="SelectionBrush" Value="{StaticResource CoGreenDim}" />
|
||||
<Setter Property="Padding" Value="9,7" />
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
</Style>
|
||||
<Style Selector="TextBox:pointerover /template/ Border#PART_BorderElement">
|
||||
<Setter Property="BorderBrush" Value="{StaticResource CoBorderBrightBrush}" />
|
||||
</Style>
|
||||
<Style Selector="TextBox:focus /template/ Border#PART_BorderElement">
|
||||
<Setter Property="BorderBrush" Value="{StaticResource CoAccentBrush}" />
|
||||
</Style>
|
||||
|
||||
<!-- Combo -->
|
||||
<Style Selector="ComboBox">
|
||||
<Setter Property="Background" Value="{StaticResource CoSurface2Brush}" />
|
||||
<Setter Property="Foreground" Value="{StaticResource CoTextBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource CoBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="5" />
|
||||
<Setter Property="Padding" Value="9,6" />
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
</Style>
|
||||
|
||||
<!-- Checkbox -->
|
||||
<Style Selector="CheckBox">
|
||||
<Setter Property="Foreground" Value="{StaticResource CoTextBrush}" />
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
</Style>
|
||||
|
||||
<!-- Base button -->
|
||||
<Style Selector="Button">
|
||||
<Setter Property="Background" Value="{StaticResource CoSurface3Brush}" />
|
||||
<Setter Property="Foreground" Value="{StaticResource CoTextBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource CoBorderBrightBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="5" />
|
||||
<Setter Property="Padding" Value="14,7" />
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||
<Setter Property="Transitions">
|
||||
<Transitions>
|
||||
<BrushTransition Property="Background" Duration="0:0:0.12" />
|
||||
</Transitions>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style Selector="Button:pointerover /template/ ContentPresenter">
|
||||
<Setter Property="Background" Value="{StaticResource CoBorderBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource CoAccentBrush}" />
|
||||
</Style>
|
||||
<Style Selector="Button:disabled">
|
||||
<Setter Property="Opacity" Value="0.4" />
|
||||
</Style>
|
||||
|
||||
<!-- Accent (primary) button -->
|
||||
<Style Selector="Button.accent">
|
||||
<Setter Property="Background" Value="{StaticResource CoAccentButtonBrush}" />
|
||||
<Setter Property="Foreground" Value="#0C1006" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource CoAccentBrightBrush}" />
|
||||
<Setter Property="FontWeight" Value="Bold" />
|
||||
</Style>
|
||||
<Style Selector="Button.accent:pointerover /template/ ContentPresenter">
|
||||
<Setter Property="Background" Value="{StaticResource CoAccentBrightBrush}" />
|
||||
<Setter Property="Foreground" Value="#0C1006" />
|
||||
</Style>
|
||||
|
||||
<!-- Danger button -->
|
||||
<Style Selector="Button.danger">
|
||||
<Setter Property="Background" Value="#3A1E1D" />
|
||||
<Setter Property="Foreground" Value="{StaticResource CoDangerBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource CoDangerBrush}" />
|
||||
<Setter Property="FontWeight" Value="Bold" />
|
||||
</Style>
|
||||
<Style Selector="Button.danger:pointerover /template/ ContentPresenter">
|
||||
<Setter Property="Background" Value="#552726" />
|
||||
<Setter Property="Foreground" Value="#F0B4B2" />
|
||||
</Style>
|
||||
|
||||
<!-- Ghost / outline button -->
|
||||
<Style Selector="Button.ghost">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="Foreground" Value="{StaticResource CoAccentBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource CoBorderBrightBrush}" />
|
||||
</Style>
|
||||
<Style Selector="Button.ghost:pointerover /template/ ContentPresenter">
|
||||
<Setter Property="Background" Value="{StaticResource CoSurface2Brush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource CoAccentBrush}" />
|
||||
</Style>
|
||||
|
||||
<!-- Status dot -->
|
||||
<Style Selector="Ellipse.dot">
|
||||
<Setter Property="Fill" Value="{StaticResource CoDangerBrush}" />
|
||||
</Style>
|
||||
<Style Selector="Ellipse.dot.on">
|
||||
<Setter Property="Fill" Value="{StaticResource CoGreenBrush}" />
|
||||
</Style>
|
||||
|
||||
<!-- Status pill: glow green when running, quiet red when stopped -->
|
||||
<Style Selector="Border.pill">
|
||||
<Setter Property="BorderBrush" Value="{StaticResource CoBorderBrightBrush}" />
|
||||
<Setter Property="Transitions">
|
||||
<Transitions>
|
||||
<BrushTransition Property="BorderBrush" Duration="0:0:0.2" />
|
||||
</Transitions>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style Selector="Border.pill.on">
|
||||
<Setter Property="BorderBrush" Value="{StaticResource CoGreenBrush}" />
|
||||
<Setter Property="BoxShadow" Value="0 0 16 0 #558BD05C" />
|
||||
</Style>
|
||||
|
||||
<!-- Cards lift off the background -->
|
||||
<Style Selector="Border.card">
|
||||
<Setter Property="BoxShadow" Value="0 3 14 0 #4D000000" />
|
||||
</Style>
|
||||
|
||||
<!-- ListBox rows -->
|
||||
<Style Selector="ListBox">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Style>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Padding" Value="6,4" />
|
||||
<Setter Property="CornerRadius" Value="4" />
|
||||
</Style>
|
||||
<Style Selector="ListBoxItem:selected /template/ ContentPresenter">
|
||||
<Setter Property="Background" Value="{StaticResource CoSurface3Brush}" />
|
||||
</Style>
|
||||
|
||||
</Application.Styles>
|
||||
|
||||
</Application>
|
||||
|
||||
+14
-2
@@ -25,7 +25,19 @@ server — a published `CommonwealthOnline.Server` executable, the framework
|
||||
|
||||
## Publish
|
||||
|
||||
Self-contained, single-file builds that need no .NET runtime on the target.
|
||||
The host uses reflection-based Avalonia bindings, so publish **untrimmed**.
|
||||
|
||||
```
|
||||
dotnet publish host/CommonwealthOnline.Host.csproj -c Release -r win-x64 --self-contained false
|
||||
dotnet publish host/CommonwealthOnline.Host.csproj -c Release -r linux-x64 --self-contained false
|
||||
dotnet publish host/CommonwealthOnline.Host.csproj -c Release -r win-x64 \
|
||||
--self-contained true -p:PublishSingleFile=true \
|
||||
-p:IncludeNativeLibrariesForSelfExtract=true -o out/win-x64
|
||||
|
||||
dotnet publish host/CommonwealthOnline.Host.csproj -c Release -r linux-x64 \
|
||||
--self-contained true -p:PublishSingleFile=true \
|
||||
-p:IncludeNativeLibrariesForSelfExtract=true -o out/linux-x64
|
||||
```
|
||||
|
||||
CI builds both runtimes and uploads them as artifacts — run the
|
||||
**Publish Host (Avalonia)** workflow (`.github/workflows/publish-host.yml`)
|
||||
manually, or push a `host-v*` tag.
|
||||
|
||||
+177
-73
@@ -3,102 +3,206 @@
|
||||
xmlns:vm="clr-namespace:CommonwealthOnline.Host.ViewModels"
|
||||
x:Class="CommonwealthOnline.Host.Views.MainWindow"
|
||||
x:DataType="vm:MainWindowViewModel"
|
||||
Width="960" Height="700"
|
||||
MinWidth="820" MinHeight="600"
|
||||
Width="1040" Height="740"
|
||||
MinWidth="900" MinHeight="640"
|
||||
Title="Commonwealth Online — Server Host"
|
||||
Background="{StaticResource CoBackgroundBrush}">
|
||||
Background="{StaticResource CoWindowBrush}">
|
||||
|
||||
<Grid RowDefinitions="Auto,*,Auto" Margin="18">
|
||||
<Grid RowDefinitions="Auto,*,Auto">
|
||||
|
||||
<Image Grid.Row="0" Source="/Assets/logo.png" Height="84"
|
||||
HorizontalAlignment="Left" Margin="0,0,0,14" />
|
||||
<!-- ============ Header ============ -->
|
||||
<Border Grid.Row="0" Background="{StaticResource CoBarBrush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="0,0,0,1"
|
||||
Padding="20,12">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto" VerticalAlignment="Center">
|
||||
|
||||
<Grid Grid.Row="1" ColumnDefinitions="330,*">
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="14" VerticalAlignment="Center">
|
||||
<Image Source="/Assets/logo.png" Height="42" VerticalAlignment="Center" />
|
||||
<StackPanel VerticalAlignment="Center" Spacing="1">
|
||||
<TextBlock Text="COMMONWEALTH ONLINE" Foreground="{StaticResource CoAccentBrush}"
|
||||
FontWeight="Bold" FontSize="16" LetterSpacing="3" />
|
||||
<TextBlock Text="DEDICATED SERVER HOST" Foreground="{StaticResource CoMutedBrush}"
|
||||
FontSize="10" LetterSpacing="4" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="0" Spacing="9" Margin="0,0,18,0">
|
||||
<TextBlock Text="SERVER" Foreground="{StaticResource CoAccentBrush}"
|
||||
FontWeight="Bold" FontSize="13" />
|
||||
<TextBox Watermark="Server name" Text="{Binding ServerName}" />
|
||||
<Grid ColumnDefinitions="*,*">
|
||||
<TextBox Grid.Column="0" Watermark="Host" Text="{Binding Host}" Margin="0,0,4,0" />
|
||||
<TextBox Grid.Column="1" Watermark="Port" Text="{Binding Port}" Margin="4,0,0,0" />
|
||||
</Grid>
|
||||
<Grid ColumnDefinitions="*,*">
|
||||
<TextBox Grid.Column="0" Watermark="Max players" Text="{Binding MaxPlayers}" Margin="0,0,4,0" />
|
||||
<TextBox Grid.Column="1" Watermark="Admin port" Text="{Binding AdminPort}" Margin="4,0,0,0" />
|
||||
</Grid>
|
||||
<TextBlock Text="LOG VERBOSITY" Foreground="{StaticResource CoAccentBrush}"
|
||||
FontWeight="Bold" FontSize="12" Margin="0,4,0,0" />
|
||||
<ComboBox HorizontalAlignment="Stretch"
|
||||
ItemsSource="{Binding VerbosityOptions}"
|
||||
SelectedItem="{Binding LogVerbosity}" />
|
||||
<CheckBox Content="Enable GNS transport" IsChecked="{Binding EnableGnsTransport}"
|
||||
Foreground="{StaticResource CoTextBrush}" />
|
||||
<Button Content="Save config" Command="{Binding SaveCommand}"
|
||||
HorizontalAlignment="Stretch" />
|
||||
</StackPanel>
|
||||
<!-- Live status pill -->
|
||||
<Border Grid.Column="2" Classes="pill" Classes.on="{Binding IsRunning}"
|
||||
Background="{StaticResource CoSurface2Brush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="14" Padding="14,7" VerticalAlignment="Center">
|
||||
<StackPanel Orientation="Horizontal" Spacing="9" VerticalAlignment="Center">
|
||||
<Ellipse Classes="dot" Classes.on="{Binding IsRunning}"
|
||||
Width="10" Height="10" VerticalAlignment="Center" />
|
||||
<TextBlock Text="{Binding StatusText}" Foreground="{StaticResource CoTextBrush}"
|
||||
FontWeight="SemiBold" FontSize="13" LetterSpacing="1"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- ============ Body ============ -->
|
||||
<Grid Grid.Row="1" ColumnDefinitions="352,*" Margin="20,18,20,14">
|
||||
|
||||
<!-- Config card -->
|
||||
<Border Grid.Column="0" Classes="card" Background="{StaticResource CoSurfaceBrush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="1"
|
||||
CornerRadius="8" Padding="18" Margin="0,0,18,0">
|
||||
<StackPanel Spacing="12">
|
||||
<TextBlock Classes="section" Text="CONFIGURATION" />
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Classes="fieldlabel" Text="SERVER NAME" />
|
||||
<TextBox Watermark="My Commonwealth server" Text="{Binding ServerName}" />
|
||||
</StackPanel>
|
||||
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" Spacing="4" Margin="0,0,8,0">
|
||||
<TextBlock Classes="fieldlabel" Text="HOST ADDRESS" />
|
||||
<TextBox Watermark="0.0.0.0" Text="{Binding Host}" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1" Spacing="4" Width="96">
|
||||
<TextBlock Classes="fieldlabel" Text="PORT" />
|
||||
<TextBox Watermark="7777" Text="{Binding Port}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" Spacing="4" Margin="0,0,8,0">
|
||||
<TextBlock Classes="fieldlabel" Text="MAX PLAYERS" />
|
||||
<TextBox Watermark="16" Text="{Binding MaxPlayers}" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1" Spacing="4" Width="96">
|
||||
<TextBlock Classes="fieldlabel" Text="ADMIN PORT" />
|
||||
<TextBox Watermark="7779" Text="{Binding AdminPort}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Classes="fieldlabel" Text="LOG VERBOSITY" />
|
||||
<ComboBox HorizontalAlignment="Stretch"
|
||||
ItemsSource="{Binding VerbosityOptions}"
|
||||
SelectedItem="{Binding LogVerbosity}" />
|
||||
</StackPanel>
|
||||
|
||||
<Border Background="{StaticResource CoSurface2Brush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="1"
|
||||
CornerRadius="5" Padding="10,8" Margin="0,2,0,0">
|
||||
<CheckBox Content="Enable GNS transport (UDP)"
|
||||
IsChecked="{Binding EnableGnsTransport}" />
|
||||
</Border>
|
||||
|
||||
<Button Classes="ghost" Content="Save configuration"
|
||||
Command="{Binding SaveCommand}"
|
||||
HorizontalAlignment="Stretch" Margin="0,4,0,0" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Right column: log + players -->
|
||||
<Grid Grid.Column="1" RowDefinitions="*,Auto">
|
||||
|
||||
<Border Grid.Row="0" Background="{StaticResource CoSurfaceBrush}"
|
||||
CornerRadius="4" Padding="10">
|
||||
<ScrollViewer>
|
||||
<ItemsControl ItemsSource="{Binding Log}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}" Foreground="{StaticResource CoTextBrush}"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace" FontSize="12"
|
||||
TextWrapping="Wrap" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
<!-- Server log -->
|
||||
<Border Grid.Row="0" Classes="card" Background="{StaticResource CoSurfaceBrush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="1"
|
||||
CornerRadius="8" Padding="0">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<Border Grid.Row="0" Background="{StaticResource CoSurface2Brush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="0,0,0,1"
|
||||
CornerRadius="8,8,0,0" Padding="14,9">
|
||||
<StackPanel Orientation="Horizontal" Spacing="9">
|
||||
<Ellipse Classes="dot" Classes.on="{Binding IsRunning}"
|
||||
Width="9" Height="9" VerticalAlignment="Center" />
|
||||
<TextBlock Classes="section" Text="SERVER LOG" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<ScrollViewer Grid.Row="1" Padding="14,10" x:Name="LogScroll">
|
||||
<ItemsControl ItemsSource="{Binding Log}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}" Foreground="{StaticResource CoTextBrush}"
|
||||
FontFamily="Cascadia Mono,Consolas,Menlo,monospace" FontSize="12"
|
||||
TextWrapping="Wrap" Margin="0,0,0,1" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="1" Background="{StaticResource CoSurfaceBrush}"
|
||||
CornerRadius="4" Padding="10" Margin="0,10,0,0" Height="188">
|
||||
<!-- Players -->
|
||||
<Border Grid.Row="1" Classes="card" Background="{StaticResource CoSurfaceBrush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="1"
|
||||
CornerRadius="8" Padding="0" Margin="0,14,0,0" Height="210">
|
||||
<Grid RowDefinitions="Auto,*,Auto">
|
||||
<DockPanel Grid.Row="0" Margin="0,0,0,6">
|
||||
<TextBlock DockPanel.Dock="Left" Text="PLAYERS"
|
||||
Foreground="{StaticResource CoAccentBrush}" FontWeight="Bold" FontSize="12" />
|
||||
<TextBlock DockPanel.Dock="Right" Text="{Binding StatsText}"
|
||||
Foreground="{StaticResource CoTextBrush}" FontSize="11"
|
||||
HorizontalAlignment="Right" />
|
||||
</DockPanel>
|
||||
<ListBox Grid.Row="1" Background="Transparent"
|
||||
<Border Grid.Row="0" Background="{StaticResource CoSurface2Brush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="0,0,0,1"
|
||||
CornerRadius="8,8,0,0" Padding="14,9">
|
||||
<DockPanel>
|
||||
<TextBlock DockPanel.Dock="Left" Classes="section" Text="PLAYERS"
|
||||
VerticalAlignment="Center" />
|
||||
<TextBlock DockPanel.Dock="Right" Text="{Binding StatsText}"
|
||||
Foreground="{StaticResource CoMutedBrush}" FontSize="11"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center" />
|
||||
</DockPanel>
|
||||
</Border>
|
||||
|
||||
<ListBox Grid.Row="1" Margin="6,4"
|
||||
ItemsSource="{Binding Players}" SelectedItem="{Binding SelectedPlayer}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Display}" Foreground="{StaticResource CoTextBrush}"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace" FontSize="12" />
|
||||
<DataTemplate x:DataType="vm:PlayerRow">
|
||||
<Grid ColumnDefinitions="52,*,Auto" >
|
||||
<TextBlock Grid.Column="0" Text="{Binding PlayerId, StringFormat='#{0}'}"
|
||||
Foreground="{StaticResource CoAccentBrush}" FontWeight="Bold"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace" FontSize="12"
|
||||
VerticalAlignment="Center" />
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="0">
|
||||
<TextBlock Text="{Binding Label}" Foreground="{StaticResource CoTextBrush}"
|
||||
FontSize="13" />
|
||||
<TextBlock Text="{Binding Address}" Foreground="{StaticResource CoMutedBrush}"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace" FontSize="10" />
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="2"
|
||||
Text="{Binding PacketsReceived, StringFormat='↓{0}'}"
|
||||
Foreground="{StaticResource CoMutedBrush}"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace" FontSize="11"
|
||||
VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" Spacing="8" Margin="0,6,0,0">
|
||||
<Button Content="Kick" Command="{Binding KickCommand}" Padding="18,4" />
|
||||
<Button Content="Ban" Command="{Binding BanCommand}" Padding="18,4"
|
||||
Background="{StaticResource CoDangerBrush}" Foreground="White" />
|
||||
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" Spacing="8"
|
||||
HorizontalAlignment="Right" Margin="10,0,10,10">
|
||||
<Button Content="Kick" Command="{Binding KickCommand}" Padding="22,5" />
|
||||
<Button Classes="danger" Content="Ban" Command="{Binding BanCommand}" Padding="22,5" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="2" ColumnDefinitions="Auto,*,Auto,Auto" Margin="0,14,0,0">
|
||||
<TextBlock Grid.Column="0" Text="Status:" Foreground="{StaticResource CoTextBrush}"
|
||||
VerticalAlignment="Center" Margin="0,0,6,0" />
|
||||
<TextBlock Grid.Column="1" Text="{Binding StatusText}"
|
||||
Foreground="{StaticResource CoAccentBrush}" FontWeight="Bold"
|
||||
VerticalAlignment="Center" />
|
||||
<Button Grid.Column="2" Content="Start" Command="{Binding StartCommand}"
|
||||
Margin="0,0,8,0" Padding="26,7"
|
||||
Background="{StaticResource CoAccentBrush}" Foreground="#0E120B" FontWeight="Bold" />
|
||||
<Button Grid.Column="3" Content="Stop" Command="{Binding StopCommand}"
|
||||
Padding="26,7"
|
||||
Background="{StaticResource CoDangerBrush}" Foreground="White" FontWeight="Bold" />
|
||||
</Grid>
|
||||
<!-- ============ Control bar ============ -->
|
||||
<Border Grid.Row="2" Background="{StaticResource CoBarBrush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="0,1,0,0"
|
||||
Padding="20,14">
|
||||
<Grid ColumnDefinitions="*,Auto,Auto">
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="8" VerticalAlignment="Center">
|
||||
<TextBlock Text="●" Foreground="{StaticResource CoMutedBrush}" FontSize="10"
|
||||
VerticalAlignment="Center" />
|
||||
<TextBlock Text="Local admin channel · 127.0.0.1"
|
||||
Foreground="{StaticResource CoMutedBrush}" FontSize="11"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
<Button Grid.Column="1" Classes="accent" Content="▶ START SERVER"
|
||||
Command="{Binding StartCommand}" Margin="0,0,10,0" Padding="26,9"
|
||||
FontSize="14" />
|
||||
<Button Grid.Column="2" Classes="danger" Content="■ STOP"
|
||||
Command="{Binding StopCommand}" Padding="26,9" FontSize="14" />
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
Reference in New Issue
Block a user