21 Commits

Author SHA1 Message Date
Timerix 4ae26cab92 some fixes 2022-03-13 17:18:34 +03:00
Timerix c201f11ce1 fixed dependencies 2022-03-13 13:47:40 +03:00
Timerix 538db682f3 it can be compiled, but doesn't work 2021-10-30 13:46:48 +03:00
Timerix 17915621f3 new dtsod parser 2021-07-21 22:54:35 +03:00
Timerix 4957b7a406 Merge branch 'master' of https://github.com/Timerix22/dtlauncher 2021-07-20 20:31:34 +03:00
Timerix ac9ef98cf9 FileWork update 2021-07-20 20:31:27 +03:00
Timerix22 f5a6d0c9f0 Rename NetWork.cs to Network.cs 2021-07-20 16:24:44 +03:00
Timerix22 1eea55a0a8 Rename FileWork.cs to Filework.cs 2021-07-20 16:24:26 +03:00
Timerix 2fc547a117 changed DTLib.FIlework for partly replace System.IO 2021-07-20 16:22:42 +03:00
Timerix 7e678ec198 added dtlib 2021-07-20 13:17:48 +03:00
Timerix22 3a0a1a027e Delete .editorconfig 2021-07-19 21:40:36 +03:00
Timerix22 27b2741af4 Delete installer directory 2021-07-19 21:40:19 +03:00
Timerix22 bc925cca61 Delete .old 6 directory 2021-07-19 21:35:46 +03:00
Timerix22 9afa03d9ee Delete .old 5 directory 2021-07-19 21:35:39 +03:00
Timerix22 126082a5bb Delete .old 4 directory 2021-07-19 21:35:32 +03:00
Timerix22 87750d4dbd Delete .old 3 directory 2021-07-19 21:35:23 +03:00
Timerix22 15111f5be4 Delete .old 1 directory 2021-07-19 21:35:17 +03:00
Timerix22 b066dfabf2 Delete .old 0 directory 2021-07-19 21:35:11 +03:00
Timerix22 308d6737ad Delete .old 2 directory 2021-07-19 21:35:04 +03:00
User 99ba577733 Добавьте файлы проекта. 2021-07-19 21:25:07 +03:00
User 93934555f6 Добавьте GITIGNORE- и GITATTRIBUTES-файлы. 2021-07-19 21:25:05 +03:00
54 changed files with 2811 additions and 1199 deletions
+165
View File
@@ -0,0 +1,165 @@
<Application x:Class="dtlauncher_client_win.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:dtlauncher_client_win">
<Application.Resources>
<ControlTemplate x:Key="myScrollBar" TargetType="{x:Type ScrollBar}">
<Grid x:Name="Bg" SnapsToDevicePixels="True">
<Border BorderBrush="Transparent" BorderThickness="0"
Background="{Binding Background, RelativeSource={RelativeSource TemplatedParent}}" Grid.Row="1"/>
<Track x:Name="PART_Track" IsDirectionReversed="True" IsEnabled="{TemplateBinding IsMouseOver}" Grid.Row="1">
<Track.Thumb>
<Thumb>
<Thumb.Style>
<Style TargetType="{x:Type Thumb}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border x:Name="rectangle" CornerRadius="2" Background="#FF9A9FC5" Height="{TemplateBinding Height}" SnapsToDevicePixels="True" Width="{TemplateBinding Width}"/>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="rectangle" Value="#FF9A9FC5"/>
</Trigger>
<Trigger Property="IsDragging" Value="True">
<Setter Property="Background" TargetName="rectangle" Value="#FF515ED1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Thumb.Style>
</Thumb>
</Track.Thumb>
</Track>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="myScrollViewer" TargetType="{x:Type ScrollViewer}">
<Grid x:Name="Grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle x:Name="Corner" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/>
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
<ScrollBar Template="{DynamicResource myScrollBar}" Background="{Binding Background, RelativeSource={RelativeSource TemplatedParent}}" x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
<ScrollBar Template="{DynamicResource myScrollBar}" Background="{Binding Background, RelativeSource={RelativeSource TemplatedParent}}" x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="myTabControl" TargetType="{x:Type TabControl}">
<Grid KeyboardNavigation.TabNavigation="Local">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TabPanel
Name="HeaderPanel"
Grid.Row="0"
Panel.ZIndex="1"
Margin="0,0,4,0"
IsItemsHost="True"
KeyboardNavigation.TabIndex="1"
Background="Transparent" />
<Border
Name="Border"
Grid.Row="1"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
CornerRadius="2"
KeyboardNavigation.TabNavigation="Local"
KeyboardNavigation.DirectionalNavigation="Contained"
KeyboardNavigation.TabIndex="2" >
<ContentPresenter
Name="PART_SelectedContentHost"
Margin="4"
ContentSource="SelectedContent"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#FFF0F0F0" />
<Setter TargetName="Border" Property="BorderBrush" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="myTabItem" TargetType="{x:Type TabItem}">
<Grid>
<Border
x:Name="Border"
Margin="0,0,-4,0"
Background="#FF4D4D4D"
BorderBrush="#FF73C300"
BorderThickness="2,2,2,2"
CornerRadius="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}" >
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"
RecognizesAccessKey="True"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="Background" Value="#FF0A11A2" />
<Setter TargetName="Border" Property="BorderThickness" Value="3,3,3,3" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="Transparent" />
<Setter TargetName="Border" Property="BorderBrush" Value="Transparent" />
<Setter Property="Foreground" Value="white" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="myTextBox" TargetType="{x:Type TextBoxBase}">
<Border
Name="Border"
Padding="2"
Background="{Binding Background, RelativeSource={RelativeSource TemplatedParent}}"
BorderBrush="Transparent"
BorderThickness="1" >
<ScrollViewer Margin="0" x:Name="PART_ContentHost" Template="{DynamicResource myScrollViewer}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="Black"/>
<Setter TargetName="Border" Property="BorderBrush" Value="White"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="roundedButton" TargetType="Button">
<Border x:Name="Border"
Background="{Binding Background, RelativeSource={RelativeSource TemplatedParent}}"
BorderBrush="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}"
BorderThickness="{Binding BorderThickness, RelativeSource={RelativeSource TemplatedParent}}"
CornerRadius="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}">
<ContentPresenter Margin="2" HorizontalAlignment="Center"
VerticalAlignment="Center" RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="#FF4E4E59"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background" Value="#FF38384F"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Application.Resources>
</Application>
+34
View File
@@ -0,0 +1,34 @@
using System;
using System.Diagnostics;
using System.Windows;
using DTLib.Filesystem;
namespace dtlauncher_client_win
{
/// <summary>
/// Логика взаимодействия для App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
try
{
if (e.Args.Length > 0 && e.Args[0] == "updated")
{
LoginWindow window = new();
window.ShowDialog();
}
else
{
if (!File.Exists("updater.exe")) throw new Exception("file <updater.exe> not found");
Process.Start("cmd", "/c timeout 1 && start updater.exe");
}
}
catch (Exception ex)
{ MessageBox.Show($"STARTUP ERROR:\n{ex.Message}\n{ex.StackTrace}"); }
//Current.Shutdown();
}
}
}
+98
View File
@@ -0,0 +1,98 @@
<Window x:Class="dtlauncher_client_win.LauncherWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:dtlauncher_client_win"
mc:Ignorable="d"
Title="DTLauncher" Width="800" Height="500" MinWidth="800" MinHeight="500" Background="#FF232328">
<Grid x:Name="MainGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="40"/>
<RowDefinition Height="8"/>
<RowDefinition/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Rectangle Fill="#FF474747" Grid.Row="2" Grid.ColumnSpan="3" Margin="0,5,0,0"/>
<Grid Grid.Column="1" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="8"/>
<ColumnDefinition/>
<ColumnDefinition Width="8"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button x:Name="HomeButton" Content="Home" FontWeight="Bold" FontFamily="Unispace" FontSize="20"
Grid.Column="0" Background="Transparent" Foreground="#FF2CDA11"
BorderThickness="3" Template="{DynamicResource roundedButton}"/>
<Button x:Name="LogButton" Content="Log" FontWeight="Bold" FontFamily="Unispace" FontSize="20"
Grid.Column="2" Background="Transparent" Foreground="#FFF0F0F0"
BorderThickness="3" Template="{DynamicResource roundedButton}"/>
<Button x:Name="SettingsButton" Content="Settings" FontWeight="Bold" FontFamily="Unispace" FontSize="20"
Grid.Column="4" Background="Transparent" Foreground="#FFF0F0F0"
BorderThickness="3" Template="{DynamicResource roundedButton}"/>
</Grid>
<Grid x:Name="HomeGrid" Visibility="Visible" Grid.Row="3" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="240"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<Rectangle Fill="#FF474747" Grid.Column="1" Margin="3,0,3,-10"/>
<Rectangle Fill="#FF474747" Grid.Column="3" Margin="3,0,3,-10"/>
<ScrollViewer x:Name="ProgramsScrollViever" Template="{DynamicResource myScrollViewer}"
Grid.Column="0" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel x:Name="ProgramsPanel">
</StackPanel>
</ScrollViewer>
<Image x:Name="BackgroundImage" Grid.Column="2" HorizontalAlignment="Stretch" Stretch="Fill" Margin="0,40,0,0" />
<Label x:Name="NameLabel" Grid.Column="2" Grid.Row="0" Margin="0,0,0,361"
FontSize="16" FontWeight="Bold" FontFamily="Unispace" Foreground="#FFF0F0F0"/>
<Button x:Name="InstallButton" Content="Install" FontWeight="Bold" FontFamily="Unispace" FontSize="17"
Grid.Column="2" Background="#FFB97523" Foreground="#FFF0F0F0"
BorderThickness="3" Template="{DynamicResource roundedButton}" Margin="0,72,167,0"
HorizontalAlignment="Right" Width="123" Height="37" VerticalAlignment="Top"/>
<Button x:Name="LaunchButton" Content="Launch" FontWeight="Bold" FontFamily="Unispace" FontSize="17"
Grid.Column="2" Background="#FFB97523" Foreground="#FFF0F0F0"
BorderThickness="3" Template="{DynamicResource roundedButton}" Margin="0,72,20,0"
HorizontalAlignment="Right" Width="123" Height="37" VerticalAlignment="Top"/>
<TextBox x:Name="DescriptionBox" Template="{DynamicResource myTextBox}" Opacity="0.8"
VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" BorderThickness="0"
Background="#FF141419" Foreground="#FFF0F0F0" SelectionBrush="#FF3E759E"
FontSize="14" IsReadOnly="True" Grid.Column="2" Grid.Row="0" Margin="0,160,0,0"/>
<Border BorderBrush="#FF141419" BorderThickness="1" Grid.Column="2" Grid.Row="0" Margin="0,160,0,0"/>
<ScrollViewer x:Name="DownloadsScrollViever" Template="{DynamicResource myScrollViewer}" VerticalContentAlignment="Top"
Grid.Column="4" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel x:Name="DownloadsPanel">
</StackPanel>
</ScrollViewer>
</Grid>
<Grid x:Name="LogGrid" Visibility="Hidden" Grid.Row="3" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="34"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<Label x:Name="LogfileLabel" Content="logfile" Grid.Column="0" Grid.Row="0"
FontSize="20" FontWeight="Bold" FontFamily="Unispace" Foreground="#FFF0F0F0"/>
<TextBox x:Name="LogBox" Template="{DynamicResource myTextBox}"
VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" BorderThickness="0"
Background="#FF141419" Foreground="#FFF0F0F0" SelectionBrush="#FF3E759E"
FontSize="14" IsReadOnly="True" Grid.Column="0" Grid.Row="1"/>
</Grid>
<Grid x:Name="SettingsGrid" Visibility="Hidden" Grid.Row="3" Grid.Column="1">
</Grid>
</Grid>
</Window>
@@ -0,0 +1,118 @@
using System;
using System.Net.Sockets;
using System.Text;
using System.Windows;
using DTLib;
using DTLib.Filesystem;
namespace dtlauncher_client_win
{
/// <summary>
/// Логика взаимодействия для LauncherWindow.xaml
/// </summary>
public partial class LauncherWindow : Window
{
public Socket mainSocket;
string logfile;
public delegate void LaunchDel();
public LaunchDel Launch = () => { };
public delegate void InstallDel();
public LaunchDel Install = () => { };
public ProgramLabel[] programsArray;
public int PreviousProgramNum = 0;
public LauncherWindow(Socket _socket, string _logfile, string _log)
{
try
{
InitializeComponent();
mainSocket = _socket;
logfile = _logfile;
LogBox.Text += _log;
PublicLog.LogEvent += Log;
PublicLog.LogNoTimeEvent += Log;
Closed += AppClose;
// переключение вкладок кнопками
var green = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(44, 220, 17));
var white = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(240, 240, 240));
HomeButton.Click += (s, e) =>
{
LogGrid.Visibility = Visibility.Hidden;
SettingsGrid.Visibility = Visibility.Hidden;
HomeGrid.Visibility = Visibility.Visible;
LogButton.Foreground = white;
SettingsButton.Foreground = white;
HomeButton.Foreground = green;
};
LogButton.Click += (s, e) =>
{
HomeGrid.Visibility = Visibility.Hidden;
SettingsGrid.Visibility = Visibility.Hidden;
LogGrid.Visibility = Visibility.Visible;
HomeButton.Foreground = white;
SettingsButton.Foreground = white;
LogButton.Foreground = green;
};
SettingsButton.Click += (s, e) =>
{
HomeGrid.Visibility = Visibility.Hidden;
LogGrid.Visibility = Visibility.Hidden;
SettingsGrid.Visibility = Visibility.Visible;
HomeButton.Foreground = white;
LogButton.Foreground = white;
SettingsButton.Foreground = green;
};
// считывание дескрипторов программ
string[] descriptors = Directory.GetFiles("descriptors", "*.desc");
programsArray = new ProgramLabel[descriptors.Length];
Log(descriptors.Length + " descriptors found\n");
for (int i = 0; i < descriptors.Length; i++)
{
programsArray[i] = new ProgramLabel(descriptors[i], i, this);
ProgramsPanel.Children.Add(programsArray[i]);
Log(programsArray[i].Text + " added to ProgramsPanel\n");
}
LaunchButton.Click += (s, e) => Launch();
InstallButton.Click += (s, e) => Install();
//mainSocket.FSP_Download(new FSP_FileObject("share\\file.arc", "downloads\\file.arc"));
}
catch (Exception ex)
{
string mes = $"LauncherWindow() error:\n{ex.Message}\n{ex.StackTrace}\n";
MessageBox.Show(mes);
Log(mes);
}
}
public void Log(string msg)
{
if (LogBox.Text[LogBox.Text.Length - 1] == '\n') msg = "[" + DateTime.Now.ToString() + "]: " + msg;
File.AppendAllText(logfile, msg);
LogBox.Text += msg;
}
public void Log(params string[] input)
{
if (input.Length == 1) Log(input[0]);
if (input.Length % 2 == 0)
{
StringBuilder strB = new();
for (ushort i = 0; i < input.Length; i++)
strB.Append(input[++i]);
Log(strB.ToString());
}
else throw new Exception("error in Log(): every text string must have color string before");
}
void AppClose(object sender, EventArgs e)
{
if (mainSocket.Connected)
{
mainSocket.Shutdown(SocketShutdown.Both);
mainSocket.Close();
}
Log("dtlauncher closing\n");
App.Current.Shutdown();
}
}
}
+51
View File
@@ -0,0 +1,51 @@
<Window x:Class="dtlauncher_client_win.LoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:dtlauncher_client_win"
mc:Ignorable="d"
Title="DTLauncher login window" Width="500" Height="350" Background="#FF232328" MinWidth="500" MinHeight="350">
<Grid ScrollViewer.VerticalScrollBarVisibility="Disabled" Margin="0" MinWidth="492" MinHeight="320">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25*"/>
<RowDefinition Height="174*"/>
<RowDefinition Height="23*"/>
<RowDefinition Height="72*"/>
<RowDefinition Height="25*"/>
</Grid.RowDefinitions>
<Canvas Height="200" Margin="20,14,20,8" Width="450" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.ColumnSpan="3" Grid.RowSpan="3">
<TextBox x:Name="LoginBox" HorizontalAlignment="Center" Height="30" TextWrapping="Wrap" Text="" VerticalAlignment="Center"
Width="300" RenderTransformOrigin="0.534,-0.193" Background="#FF4B4B5A" Foreground="#FFF0F0F0" SelectionBrush="#FF2E628B"
FontSize="17" BorderThickness="2" IsUndoEnabled="False" MaxLength="25" MaxLines="1" BorderBrush="#FFF0F0F0" MinWidth="300"
MinHeight="29" Canvas.Left="130" Canvas.Top="21"/>
<PasswordBox x:Name="PasswBox" HorizontalAlignment="Center" VerticalAlignment="Center" Width="300" Height="30" FontSize="17"
Background="#FF4B4B5A" Foreground="#FFF0F0F0" SelectionBrush="#FF2E628B" MaxLength="25" BorderThickness="2"
BorderBrush="#FFF0F0F0" MinWidth="300" MinHeight="30" Canvas.Left="130" Canvas.Top="83"/>
<Label Content="login:" HorizontalAlignment="Center" VerticalAlignment="Center" Height="40" Width="90" Foreground="#FFF0F0F0"
FontSize="20" FontWeight="Bold" RenderTransformOrigin="0.764,0.578" FontFamily="Unispace" MinWidth="74" MinHeight="40"
VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Canvas.Left="34" Canvas.Top="17"/>
<Label Content="password:" HorizontalAlignment="Center" VerticalAlignment="Center" Height="40" Width="119" Foreground="#FFF0F0F0"
FontSize="20" FontWeight="Bold" FontFamily="Unispace" MinHeight="40" MinWidth="111" VerticalContentAlignment="Center"
HorizontalContentAlignment="Center" Canvas.Left="1" Canvas.Top="77"/>
<Button x:Name="RegisterButton" Content="register" Width="117" Height="40" FontSize="20"
FontWeight="Bold" Foreground="#FFF0F0F0" Background="#FF383844"
FontFamily="Unispace" BorderThickness="3" MinHeight="40" MinWidth="117" HorizontalAlignment="Center"
VerticalAlignment="Center" Canvas.Left="71" Canvas.Top="138" Template="{DynamicResource roundedButton}"/>
<Button x:Name="LoginButton" Content="login" Width="117" Height="40" FontSize="20" FontWeight="Bold"
Foreground="#FFF0F0F0" Background="#FFB97523" FontFamily="Unispace"
BorderThickness="3" MinHeight="40" MinWidth="117" HorizontalAlignment="Center" VerticalAlignment="Center"
Canvas.Left="272" Canvas.Top="138" Template="{DynamicResource roundedButton}"/>
</Canvas>
<TextBox x:Name="LogBox" Template="{DynamicResource myTextBox}"
VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" BorderThickness="0"
Background="Transparent" Foreground="#FFF0F0F0" SelectionBrush="#FF3E759E"
FontSize="14" IsReadOnly="True" Grid.Column="1" Grid.Row="3"/>
</Grid>
</Window>
+158
View File
@@ -0,0 +1,158 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows;
using DTLib;
using DTLib.Dtsod;
using DTLib.Filesystem;
using DTLib.Network;
using DTLib.Extensions;
namespace dtlauncher_client_win
{
/// <summary>
/// Логика взаимодействия для LoginWindow.xaml
/// </summary>
public partial class LoginWindow : Window
{
public Socket mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public string logfile = $"logs\\client-{DateTime.Now}.log".Replace(':', '-').Replace(' ', '_');
DtsodV21 config;
public LoginWindow()
{
try
{
InitializeComponent();
LogBox.Text = " \n"; // костыль для работы Log()
Directory.Create("logs");
Directory.Create("downloads");
Directory.Create("installed");
Directory.Create("installscripts");
Directory.Create("launchinfo");
PublicLog.LogEvent += Log;
PublicLog.LogNoTimeEvent += Log;
LoginButton.Click += Login;
RegisterButton.Click += Register;
Log("[" + DateTime.Now.ToString() + "]: launcher is starting\n");
config = new(File.ReadAllText("client.dtsod"));
Closed += AppClose;
}
catch (Exception e)
{
Log("error:\n" + e.Message + "\n" + e.StackTrace + '\n');
}
}
void Register(object sender, EventArgs e)
{
try
{
var hasher = new Hasher();
string filename = $"register-{LoginBox.Text}.req";
string content = hasher.HashCycled(hasher.Hash(LoginBox.Text.ToBytes(), PasswBox.Password.ToBytes()), 512).HashToString() + ": " + LoginBox.Text;
//File.WriteAllText(filename, hasher.HashCycled(hasher.Hash(LoginBox.Text.ToBytes(), PasswBox.Password.ToBytes()), 512).HashToString() + ": " + LoginBox.Text);
//Log($"request file created:{Directory.GetCurrentDirectory()}\\register-{LoginBox.Text}.req {hasher.Hash(LoginBox.Text.ToBytes(), PasswBox.Password.ToBytes()).Length}");
if (mainSocket.Connected)
{
mainSocket.Shutdown(SocketShutdown.Both);
mainSocket.Close();
mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
Log($"server address: <{config["server_domain"]}>\nserver port: <{config["server_port"]}>\n");
mainSocket.Connect(new IPEndPoint(Dns.GetHostAddresses(config["server_domain"])[0], (int)config["server_port"]));
Log("g", "connecting to server...\n");
mainSocket.ReceiveTimeout = 2000;
string recieved = mainSocket.GetPackage().BytesToString();
if (recieved != "requesting hash") throw new Exception($"Login() error: invalid request <{recieved}> <{recieved.Length}>");
mainSocket.SendPackage(new byte[] { 255, 255, 255, 255, 255, 255, 255, 255 });
recieved = mainSocket.GetPackage().BytesToString();
if (recieved != "updater") throw new Exception($"invalid central server answer <{recieved}>");
mainSocket.SendPackage("register new user".ToBytes());
recieved = mainSocket.GetPackage().BytesToString();
if (recieved != "ok") throw new Exception($"invalid central server answer <{recieved}>");
mainSocket.SendPackage(content.ToBytes());
Log("g", "registration request sent\n");
//mainSocket.SendPackage(filename.ToBytes());
//mainSocket.FSP_Upload(filename);
//mainSocket.Shutdown(SocketShutdown.Both);
//mainSocket.Close();
}
catch (Exception ex)
{
string mes = $"LoginWindow.Register() error:\n{ex.Message}\n{ex.StackTrace}\n";
MessageBox.Show(mes);
Log(mes);
}
}
void Login(object sender, EventArgs e)
{
try
{
if (mainSocket.Connected)
{
mainSocket.Shutdown(SocketShutdown.Both);
mainSocket.Close();
mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
Log($"server address: <{config["server_domain"]}>\nserver port: <{config["server_port"]}>\n");
mainSocket.Connect(new IPEndPoint(Dns.GetHostAddresses(config["server_domain"])[0], (int)config["server_port"]));
Log("g", "connecting to server...\n");
mainSocket.ReceiveTimeout = 2000;
string recieved = mainSocket.GetPackage().BytesToString();
if (recieved != "requesting hash") throw new Exception($"Login() error: invalid request <{recieved}> <{recieved.Length}>");
var hasher = new Hasher();
mainSocket.SendPackage(hasher.HashCycled(hasher.Hash(LoginBox.Text.ToBytes(), PasswBox.Password.ToBytes()), 512));
recieved = mainSocket.GetPackage().BytesToString();
if (recieved != "success") throw new Exception($"Login() error: invalid server answer <{recieved}>");
Log("succesfully connected\n");
// вызов нового окна
PublicLog.LogEvent -= Log;
PublicLog.LogNoTimeEvent -= Log;
var lauWin = new LauncherWindow(mainSocket, logfile, LogBox.Text);
lauWin.Show();
Closed -= AppClose;
Close();
}
catch (Exception ex)
{
string mes = $"LoginWindow.Login() error:\n{ex.Message}\n{ex.StackTrace}\n";
MessageBox.Show(mes);
Log(mes);
}
}
public void Log(string msg)
{
if (LogBox.Text[LogBox.Text.Length - 1] == '\n') msg = "[" + DateTime.Now.ToString() + "]: " + msg;
File.AppendAllText(logfile, msg);
LogBox.Text += msg;
}
public void Log(params string[] input)
{
if (input.Length == 1) Log(input[0]);
if (input.Length % 2 == 0)
{
StringBuilder strB = new();
for (ushort i = 0; i < input.Length; i++)
strB.Append(input[++i]);
Log(strB.ToString());
}
else throw new Exception("error in Log(): every text string must have color string before");
}
void AppClose(object sender, EventArgs e)
{
if (mainSocket.Connected)
{
mainSocket.Shutdown(SocketShutdown.Both);
mainSocket.Close();
}
Log("dtlauncher closing\n");
App.Current.Shutdown();
}
}
}
+33
View File
@@ -0,0 +1,33 @@
<UserControl x:Class="dtlauncher_client_win.ProgramLabel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:dtlauncher_client_win"
mc:Ignorable="d"
d:DesignHeight="25" d:DesignWidth="140" BorderThickness="0">
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<ContentPresenter />
</ControlTemplate>
</UserControl.Template>
<Grid x:Name="grid" Background="#FF232328" MouseLeftButtonDown="ProgramShow">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border x:Name="Border" Grid.ColumnSpan="2"
Background="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ProgramLabel}}}"
BorderBrush="{Binding BorderBrush, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ProgramLabel}}}"
BorderThickness="{Binding BorderThickness, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ProgramLabel}}}"
CornerRadius="{Binding CornerRadius, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ProgramLabel}}}"/>
<Image x:Name="IconImage" Grid.Column="0" Stretch="Fill" Margin="3,2,2,3" Width="20" Height="20"
Source="{Binding Icon, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ProgramLabel}}}"/>
<Label Name="NameLabel" Grid.Column="1" VerticalContentAlignment="Center"
Content="{Binding Text, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ProgramLabel}}}"
FontSize="{Binding FontSize, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ProgramLabel}}}"
FontFamily="{Binding FontFamily,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ProgramLabel}}}"
FontWeight="{Binding FontWeight, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ProgramLabel}}}"
Foreground="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ProgramLabel}}}"/>
</Grid>
</UserControl>
+125
View File
@@ -0,0 +1,125 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using DTLib.Dtsod;
namespace dtlauncher_client_win
{
/// <summary>
/// Логика взаимодействия для ProgramLabel.xaml
/// </summary>
public partial class ProgramLabel : UserControl
{
public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(ProgramLabel));
public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public static DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(BitmapImage), typeof(ProgramLabel));
public BitmapImage Icon
{
get => (BitmapImage)GetValue(IconProperty);
set => SetValue(IconProperty, value);
}
public static DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(ProgramLabel));
public CornerRadius CornerRadius
{
get => (CornerRadius)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
public int Number;
LauncherWindow Window;
//public string background;
//public string description;
//public string installScript;
//public string installDir;
DtsodV21 descriptor;
DtsodV21 launchinfo;
public ProgramLabel() => InitializeComponent();
public ProgramLabel(string descriptorFile, int number, LauncherWindow window)
{
try
{
InitializeComponent();
Window = window;
Number = number;
descriptor = new(File.ReadAllText(descriptorFile));
launchinfo = new(File.ReadAllText("launchinfo\\" + descriptor["id"]));
FontSize = 14;
Foreground = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(240, 240, 240));
Text = descriptor["name"];
NameLabel.Content = descriptor["name"];
IconImage.Source = new BitmapImage(new Uri(Directory.GetCurrentDirectory() + "\\icons\\" + descriptor["id"], UriKind.Absolute));
//background = Directory.GetCurrentDirectory() + "\\descriptors\\" + descriptor["background"];
//installScript = descriptor["script"];
//installDir = descriptor["installdir"];
//launchInfo = descriptor["LaunchInfo"];
//description = descriptor["description"].Replace("\\n", "\n");
//Window.Log(Text + " " + Icon + " " + Number);
}
catch (Exception ex)
{
string mes = $"ProgramLabel() error:\n{ex.Message}\n{ex.StackTrace}\n";
MessageBox.Show(mes);
Window.Log(mes);
}
}
void ProgramShow(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
try
{
Window.programsArray[Window.PreviousProgramNum].Foreground = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(240, 240, 240));
Window.programsArray[Window.PreviousProgramNum].FontWeight = FontWeights.Normal;
Window.programsArray[Window.PreviousProgramNum].FontSize = 14;
Window.PreviousProgramNum = Number;
Foreground = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(170, 170, 240));
FontWeight = FontWeights.Bold;
FontSize = 13;
Window.NameLabel.Content = Text;
Window.DescriptionBox.Text = descriptor["description"];
Window.BackgroundImage.Source = new BitmapImage(new Uri(Directory.GetCurrentDirectory() + "\\backgrounds\\" + descriptor["id"], UriKind.Absolute));
Window.Launch = () =>
{
switch (descriptor["id"])
{
case "anarx_1.12":
Window.Install();
Window.Log($"launching file <{launchinfo["launchfile"]}>\n");
Process.Start(launchinfo["launchfile"]);
break;
default:
Window.Log($"launching file <{launchinfo["launchfile"]}>\n");
Process.Start(launchinfo["launchfile"]);
break;
}
};
Window.Install = () =>
{
Window.Log($"launching installation script <{descriptor["id"]}>\n");
var scriptrunner = new DTScript.ScriptRunner
{
debug = false,
mainSocket = Window.mainSocket
};
scriptrunner.RunScriptFile("installscripts\\" + descriptor["id"]);
};
}
catch (Exception ex)
{
string mes = $"ProgramLabel.ProgramShow() error:\n{ex.Message}\n{ex.StackTrace}\n";
MessageBox.Show(mes);
Window.Log(mes);
}
}
}
}
@@ -0,0 +1,53 @@
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
// Общие сведения об этой сборке предоставляются следующим набором
// набор атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
// связанные со сборкой.
[assembly: AssemblyTitle("dtlauncher-client-win")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("dtlauncher-client-win")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
// из модели COM, установите атрибут ComVisible для этого типа в значение true.
[assembly: ComVisible(false)]
//Чтобы начать создание локализуемых приложений, задайте
//<UICulture>CultureYouAreCodingWith</UICulture> в файле .csproj
//в <PropertyGroup>. Например, при использовании английского (США)
//в своих исходных файлах установите <UICulture> в en-US. Затем отмените преобразование в комментарий
//атрибута NeutralResourceLanguage ниже. Обновите "en-US" в
//строка внизу для обеспечения соответствия настройки UICulture в файле проекта.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //где расположены словари ресурсов по конкретным тематикам
//(используется, если ресурс не найден на странице,
// или в словарях ресурсов приложения)
ResourceDictionaryLocation.SourceAssembly //где расположен словарь универсальных ресурсов
//(используется, если ресурс не найден на странице,
// в приложении или в каких-либо словарях ресурсов для конкретной темы)
)]
// Сведения о версии для сборки включают четыре следующих значения:
//
// Основной номер версии
// Дополнительный номер версии
// Номер сборки
// Номер редакции
//
// Можно задать все значения или принять номера сборки и редакции по умолчанию
// используя "*", как показано ниже:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+70
View File
@@ -0,0 +1,70 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код был создан программным средством.
// Версия среды выполнения: 4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильному поведению и будут утрачены, если
// код создан повторно.
// </auto-generated>
//------------------------------------------------------------------------------
namespace dtlauncher_client_win.Properties
{
/// <summary>
/// Класс ресурсов со строгим типом для поиска локализованных строк и пр.
/// </summary>
// Этот класс был автоматически создан при помощи StronglyTypedResourceBuilder
// класс с помощью таких средств, как ResGen или Visual Studio.
// Для добавления или удаления члена измените файл .ResX, а затем перезапустите ResGen
// с параметром /str или заново постройте свой VS-проект.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Возврат кэшированного экземпляра ResourceManager, используемого этим классом.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("dtlauncher_client_win.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Переопределяет свойство CurrentUICulture текущего потока для всех
/// подстановки ресурсов с помощью этого класса ресурсов со строгим типом.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+29
View File
@@ -0,0 +1,29 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace dtlauncher_client_win.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}
@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
+2
View File
@@ -0,0 +1,2 @@
server_domain: "m1net.keenetic.pro";
server_port: 25001;
@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{367793EE-4757-4ADD-BF7E-960DC9EB6DF9}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>dtlauncher_client_win</RootNamespace>
<AssemblyName>dtlauncher-client-win</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<LangVersion>9.0</LangVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Build|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup>
<StartupObject>dtlauncher_client_win.App</StartupObject>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>logo-D.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="LauncherWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="LoginWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="LauncherConfig.cs" />
<Compile Include="LauncherWindow.xaml.cs">
<DependentUpon>LauncherWindow.xaml</DependentUpon>
</Compile>
<Compile Include="LoginWindow.xaml.cs">
<DependentUpon>LoginWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="ProgramLabel.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="ProgramLabel.xaml.cs">
<DependentUpon>ProgramLabel.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="client.dtsod">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\DTLib\DTLib\DTLib.csproj">
<Project>{ce793497-2d5c-42d8-b311-e9b32af9cdfb}</Project>
<Name>DTLib</Name>
</ProjectReference>
<ProjectReference Include="..\dtscript\dtscript.csproj">
<Project>{e02ea967-fd29-47d2-b25b-ba684b784aee}</Project>
<Name>dtscript</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Resource Include="logo-D.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>del /f /q dtlauncher-client-win.exe.config
copy dtlauncher-client-win.exe ..\..\dtlauncher-server-win\bin\share\client\dtlauncher-client-win.exe
copy client.dtsod ..\..\dtlauncher-server-win\bin\share\client\client.dtsod</PostBuildEvent>
</PropertyGroup>
</Project>

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

+208
View File
@@ -0,0 +1,208 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using DTLib;
using DTLib.Dtsod;
using DTLib.Filesystem;
using DTLib.Network;
using DTLib.Extensions;
namespace dtlauncher_server
{
class DtlauncherServer
{
static readonly string logfile = $"logs\\dtlauncher-server-{DateTime.Now}.log".Replace(':', '-').Replace(' ', '_');
static readonly Socket mainSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
static DtsodV21 config;
static DTLib.Loggers.DefaultLogger Info = new("logs", "dtlaunchet_server");
//static readonly Dictionary<Socket, Thread> users = new();
static void Main()
{
try
{
Console.Title = "dtlauncher server";
Console.InputEncoding = Encoding.Unicode;
Console.OutputEncoding = Encoding.Unicode;
PublicLog.LogEvent += Info.Log;
PublicLog.LogNoTimeEvent += Info.Log;
/*var outBuilder = new StringBuilder();
string time = DateTime.Now.ToString().Replace(':', '-').Replace(' ', '_');
foreach (var _file in Directory.GetFiles(@"D:\!dtlauncher-server\share\public\Conan_Exiles"))
{
var file = _file.Remove(0, 35);
outBuilder.Append("Download(\"");
outBuilder.Append(file);
outBuilder.Append("\", \"downloads\\");
outBuilder.Append(file);
outBuilder.Append("\");\n");
outBuilder.Append("Run(\"cmd\", \"/c unarc.exe x -dpinstalled downloads\\");
outBuilder.Append(file);
outBuilder.Append(" >> logs\\installation-Conan_Exiles-");
outBuilder.Append(time);
outBuilder.Append(".log\");\n");
outBuilder.Append("FileDelete(\"downloads\\");
outBuilder.Append(file);
outBuilder.Append("\");\n");
}
Info.Log("c", "\n\n" + outBuilder.ToString() + "\n\n");*/
config = config = new(File.ReadAllText("server.dtsod"));
int f = (int)config["server_port"];
Info.Log("b", "local address: <", "c", config["server_ip"], "b",
">\npublic address: <", "c", OldNetwork.GetPublicIP(), "b",
">\nport: <", "c", config["server_port"].ToString(), "b", ">\n");
mainSocket.Bind(new IPEndPoint(IPAddress.Parse(config["server_ip"]), (int)config["server_port"]));
mainSocket.Listen(1000);
Info.Log("g", "server started succesfully\n");
//
/*DTLib.Timer userCkeckTimer = new(true, 3000, () =>
{
foreach (Socket usr in users.Keys)
{
if (usr.)
{
Info.Log("y", $"closing unused user <{usr.RemoteEndPoint.Serialize()[0]}> thread\n");
users[usr].Abort();
users.Remove(usr);
}
}
});*/
// запуск отдельного потока для каждого юзера
while (true)
{
Socket userSocket = mainSocket.Accept();
var userThread = new Thread(new ParameterizedThreadStart((obj) => UserHandle((Socket)obj)));
//users.Add(userSocket, userThread);
userThread.Start(userSocket);
}
}
catch (Exception ex)
{
Info.Log("r", $"dtlauncher_server.Main() error:\n{ex.Message}\n{ex.StackTrace}\n");
mainSocket.Close();
}
Info.Log("press any key to close... ");
Console.ReadKey();
Info.Log("gray", "\n");
}
// запускается для каждого юзера в отдельном потоке
static void UserHandle(Socket handlerSocket)
{
Info.Log("b", "user connecting... ");
//Socket fspSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//fspSocket.Bind()
FSP fsp = new(handlerSocket);
try
{
handlerSocket.SendPackage("requesting hash".ToBytes());
byte[] hash = handlerSocket.GetPackage();
// запрос от апдейтера
if (hash.HashToString() == "ffffffffffffffff")
{
Info.LogNoTime("c", "client is updater\n");
CreateManifest("share\\client\\");
Info.Log("g", "client files manifest created\n");
handlerSocket.SendPackage("updater".ToBytes());
while (true)
{
if (handlerSocket.Available >= 2)
{
string request = handlerSocket.GetPackage().BytesToString();
string recieved, filepath;
switch (request)
{
case "requesting file download":
filepath = "share\\client\\" + handlerSocket.GetPackage().BytesToString();
fsp.UploadFile(filepath);
break;
case "register new user":
Info.Log("b", "new user registration requested\n");
handlerSocket.SendPackage("ok".ToBytes());
//filepath = handlerSocket.GetPackage().BytesToString();
//if (!filePath.EndsWith(".req")) throw new Exception($"wrong registration request file: <{filepath}>");
//Info.Log("b", $"downloading file registration_requests\\{filepath}\n");
//handlerSocket.FSP_Download($"registration_requests\\{filepath}");
recieved = handlerSocket.GetPackage().BytesToString();
filepath = $"registration_requests\\{recieved.Remove(0, recieved.IndexOf(':') + 2)}.req";
File.WriteAllText(filepath, recieved);
Info.Log("b", $"text wrote to file <", "c", "registration_requests\\{filepath}", "b", ">\n");
break;
default:
throw new Exception("unknown request: " + request);
}
}
else Thread.Sleep(10);
}
}
// запрос от лаунчера
else
{
Info.LogNoTime("c", "client is launcher\n");
string login;
lock (new object())
{
login = OldFilework.ReadFromConfig("users.db", hash.HashToString());
}
handlerSocket.SendPackage("success".ToBytes());
Info.Log("g", "user <", "c", login, "g", "> succesfully logined\n");
while (true)
{
if (handlerSocket.Available >= 64)
{
string request = handlerSocket.GetPackage().BytesToString();
switch (request)
{
// ответ на NetWork.Ping()
/*case "ping":
handlerSocket.Send("pong".ToBytes());
break;*/
// отправка списка активных серверов
/*case "requesting servers list":
break;*/
case "requesting file download":
fsp.UploadFile("share\\public\\" + handlerSocket.GetPackage().BytesToString());
break;
default:
throw new Exception("unknown request: " + request);
}
}
else Thread.Sleep(10);
}
}
}
catch (Exception ex)
{
Info.Log("y", $"UserStart() error:\n message:\n {ex.Message}\n{ex.StackTrace}\n");
handlerSocket.Shutdown(SocketShutdown.Both);
handlerSocket.Close();
Thread.CurrentThread.Abort();
}
}
// вычисляет и записывает в manifest.dtsod хеши файлов из files_list.dtsod
public static void CreateManifest(string dir)
{
if (!dir.EndsWith("\\")) dir += "\\";
List<string> files = Directory.GetAllFiles(dir);
if (files.Contains(dir + "manifest.dtsod")) files.Remove(dir + "manifest.dtsod");
StringBuilder manifestBuilder = new();
Hasher hasher = new();
for (int i = 0; i < files.Count; i++)
{
files[i] = files[i].Remove(0, dir.Length);
manifestBuilder.Append(files[i]);
manifestBuilder.Append(": \"");
byte[] hash = hasher.HashFile(dir + files[i]);
manifestBuilder.Append(hash.HashToString());
manifestBuilder.Append("\";\n");
}
File.WriteAllText(dir + "manifest.dtsod", manifestBuilder.ToString());
}
}
}
@@ -0,0 +1,53 @@
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
// Общие сведения об этой сборке предоставляются следующим набором
// набор атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
// связанные со сборкой.
[assembly: AssemblyTitle("dtlauncher-server-win")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("dtlauncher-server-win")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
// из модели COM, установите атрибут ComVisible для этого типа в значение true.
[assembly: ComVisible(false)]
//Чтобы начать создание локализуемых приложений, задайте
//<UICulture>CultureYouAreCodingWith</UICulture> в файле .csproj
//в <PropertyGroup>. Например, при использовании английского (США)
//в своих исходных файлах установите <UICulture> в en-US. Затем отмените преобразование в комментарий
//атрибута NeutralResourceLanguage ниже. Обновите "en-US" в
//строка внизу для обеспечения соответствия настройки UICulture в файле проекта.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //где расположены словари ресурсов по конкретным тематикам
//(используется, если ресурс не найден на странице,
// или в словарях ресурсов приложения)
ResourceDictionaryLocation.SourceAssembly //где расположен словарь универсальных ресурсов
//(используется, если ресурс не найден на странице,
// в приложении или в каких-либо словарях ресурсов для конкретной темы)
)]
// Сведения о версии для сборки включают четыре следующих значения:
//
// Основной номер версии
// Дополнительный номер версии
// Номер сборки
// Номер редакции
//
// Можно задать все значения или принять номера сборки и редакции по умолчанию
// используя "*", как показано ниже:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+70
View File
@@ -0,0 +1,70 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код был создан программным средством.
// Версия среды выполнения: 4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильному поведению и будут утрачены, если
// код создан повторно.
// </auto-generated>
//------------------------------------------------------------------------------
namespace dtlauncher_server_win.Properties
{
/// <summary>
/// Класс ресурсов со строгим типом для поиска локализованных строк и пр.
/// </summary>
// Этот класс был автоматически создан при помощи StronglyTypedResourceBuilder
// класс с помощью таких средств, как ResGen или Visual Studio.
// Для добавления или удаления члена измените файл .ResX, а затем перезапустите ResGen
// с параметром /str или заново постройте свой VS-проект.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Возврат кэшированного экземпляра ResourceManager, используемого этим классом.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("dtlauncher_server_win.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Переопределяет свойство CurrentUICulture текущего потока для всех
/// подстановки ресурсов с помощью этого класса ресурсов со строгим типом.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+29
View File
@@ -0,0 +1,29 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace dtlauncher_server_win.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}
@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{8B9889A7-93DC-4914-92D1-8209BD3BA71A}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>dtlauncher_server_win</RootNamespace>
<AssemblyName>dtlauncher-server-win</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<LangVersion>9.0</LangVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Build|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject>
</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<Compile Include="DtlauncherServer.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="server.dtsod">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.8">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.8 %28x86 и x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\DTLib\DTLib\DTLib.csproj">
<Project>{ce793497-2d5c-42d8-b311-e9b32af9cdfb}</Project>
<Name>DTLib</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>del /f /q dtlauncher-server-win.exe.config</PostBuildEvent>
</PropertyGroup>
</Project>
+2
View File
@@ -0,0 +1,2 @@
server_ip: "10.1.10.44";
server_port: 25001;
+49
View File
@@ -0,0 +1,49 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31815.197
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dtlauncher-client-win", "dtlauncher-client-win\dtlauncher-client-win.csproj", "{367793EE-4757-4ADD-BF7E-960DC9EB6DF9}"
ProjectSection(ProjectDependencies) = postProject
{CE793497-2D5C-42D8-B311-E9B32AF9CDFB} = {CE793497-2D5C-42D8-B311-E9B32AF9CDFB}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dtlauncher-server-win", "dtlauncher-server-win\dtlauncher-server-win.csproj", "{8B9889A7-93DC-4914-92D1-8209BD3BA71A}"
ProjectSection(ProjectDependencies) = postProject
{CE793497-2D5C-42D8-B311-E9B32AF9CDFB} = {CE793497-2D5C-42D8-B311-E9B32AF9CDFB}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "updater", "updater\updater.csproj", "{4784D974-A342-4202-9430-90FE5AC00FC7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dtscript", "dtscript\dtscript.csproj", "{E02EA967-FD29-47D2-B25B-BA684B784AEE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DTLib", "..\DTLib\DTLib\DTLib.csproj", "{CE793497-2D5C-42D8-B311-E9B32AF9CDFB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sulution Files", "Sulution Files", "{09AA971D-CD70-4D93-BBA9-810C842830D8}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Build|Any CPU = Build|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{367793EE-4757-4ADD-BF7E-960DC9EB6DF9}.Build|Any CPU.ActiveCfg = Build|Any CPU
{367793EE-4757-4ADD-BF7E-960DC9EB6DF9}.Build|Any CPU.Build.0 = Build|Any CPU
{8B9889A7-93DC-4914-92D1-8209BD3BA71A}.Build|Any CPU.ActiveCfg = Build|Any CPU
{8B9889A7-93DC-4914-92D1-8209BD3BA71A}.Build|Any CPU.Build.0 = Build|Any CPU
{4784D974-A342-4202-9430-90FE5AC00FC7}.Build|Any CPU.ActiveCfg = Build|Any CPU
{4784D974-A342-4202-9430-90FE5AC00FC7}.Build|Any CPU.Build.0 = Build|Any CPU
{E02EA967-FD29-47D2-B25B-BA684B784AEE}.Build|Any CPU.ActiveCfg = Build|Any CPU
{E02EA967-FD29-47D2-B25B-BA684B784AEE}.Build|Any CPU.Build.0 = Build|Any CPU
{CE793497-2D5C-42D8-B311-E9B32AF9CDFB}.Build|Any CPU.ActiveCfg = Release-net48|Any CPU
{CE793497-2D5C-42D8-B311-E9B32AF9CDFB}.Build|Any CPU.Build.0 = Release-net48|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E6569C0C-DD32-4F7D-AD4C-DBC5434D2F8C}
EndGlobalSection
EndGlobal
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
</startup>
</configuration>
+33
View File
@@ -0,0 +1,33 @@
using System;
using DTLib;
using DTLib.Filesystem;
namespace DTScript;
public class MainClass
{
static DTLib.Loggers.DefaultLogger Info = new("logs", "dtlaunchet_server");
static void Main(string[] args)
{
try
{
Directory.Create("dtscript-logs");
PublicLog.LogEvent += Info.Log;
PublicLog.LogNoTimeEvent += Info.Log;
var scripter = new ScriptRunner();
if (args.Length == 0 || args.Length > 2) throw new Exception("enter script file path\n");
else if (args.Length == 1) scripter.RunScriptFile(args[0]);
else if (args.Length == 2 && args[0] == "-debug")
{
scripter.debug = true;
scripter.Debug("y", "debug is enabled\n");
scripter.RunScriptFile(args[1]);
}
else throw new Exception("unknown args\n");
}
catch (Exception ex)
{ Info.Log("r", $"dtscript.Main() error:\n{ex.Message}\n{ex.StackTrace}\n"); }
Info.Log("gray", " \n");
}
}
@@ -4,12 +4,12 @@ using System.Runtime.InteropServices;
// Общие сведения об этой сборке предоставляются следующим набором
// набора атрибутов. Измените значения этих атрибутов для изменения сведений,
// связанные с этой сборкой.
[assembly: AssemblyTitle("minecraft-launcher-client")]
[assembly: AssemblyTitle("dtscript")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("minecraft-launcher-client")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyProduct("dtscript")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -19,7 +19,7 @@ using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
// Следующий GUID представляет идентификатор typelib, если этот проект доступен из модели COM
[assembly: Guid("49adefce-da46-4229-997c-3d43dd600627")]
[assembly: Guid("e02ea967-fd29-47d2-b25b-ba684b784aee")]
// Сведения о версии сборки состоят из указанных ниже четырех значений:
//
+465
View File
@@ -0,0 +1,465 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Sockets;
using System.Linq;
using DTLib;
using DTLib.Filesystem;
using DTLib.Network;
namespace DTScript;
//
// основной класс скриптового интерпретатора
//
public class ScriptRunner
{
// выводит текст через DTLib если дебаг включен
public bool debug = false;
public Socket mainSocket;
public FSP fsp;
internal void Debug(params string[] msg)
{
if (debug) PublicLog.Log(msg);
}
// cчитывание текста из файла и запуск выполнения
public void RunScriptFile(string scriptfile)
{
Debug("g", @"----\ " + scriptfile + " /----\n");
try { Execute(SplitScript(File.ReadAllText(scriptfile))); }
catch (Exception e) { PublicLog.Log("r", $"dtscript RunScriptFile() error:\n{e.Message}\n{e.StackTrace}\n", "gray", " \n"); }
}
int globalindex = -1;
List<Dictionary<string, object>> Storage = new();
object GetValue(string key)
{
Debug("m", "GetValue(", "c", "<", "b", key, "c", ">", "m", ")\n");
for (int i = 0; i <= globalindex; i++)
if (Storage[i].ContainsKey(key)) return Storage[i][key];
throw new Exception($"GetValue() exception: storage doesn't contain key<{key}>");
}
void SetValue(string key, object value)
{
Debug("m", "SetValue(", "c", "<", "b", key, "c", "> ", "c", "<", "b", value.ToString(), "c", ">", "m", ")\n");
for (int i = 0; i <= globalindex; i++)
if (Storage[i].ContainsKey(key))
{
Storage[i][key] = value;
Debug(Storage[i][key].ToString());
return;
}//throw new Exception($"SetValue() exception: storage alredy contains key<{key}>");
Storage[globalindex].Add(key, value);
}
dynamic Execute(List<Construction> script)
{
Debug("y", " executing...\n");
// создание локального
globalindex++;
List<Construction> subscript;
Storage.Add(new Dictionary<string, object>());
// запуск цикла
for (int index = 0; index < script.Count; index++)
{
if (debug)
{
PublicLog.Log(new string[] {
"y","\noperator: ", "m",script[index].Operator, "y"," options: ", "c", "<", "b", script[index].Options[0], "c", ">"});
for (ushort n = 1; n < script[index].Options.Length; n++)
PublicLog.Log("w", ", ", "c", "<", "b", script[index].Options[n], "c", ">");
PublicLog.Log("\n");
}
switch (script[index].Operator)
{
case "return":
Debug("g", "script ended");
return GetValue(script[index].Options[0]);
case "Run":
var proc = new Process();
proc.StartInfo.FileName = script[index].Options[0].Replace("\"", "");
proc.StartInfo.Arguments = script[index].Options[1].Replace("\"", "");
/*if (script[index].Options.Length == 3 && script[index].Options[2] == "true")
{
proc.StartInfo.CreateNoWindow = true;
Debug("g", $"process {script[index].Operator} started in hidden mode\n");
}
else if (script[index].Options.Length == 3 && script[index].Options[2] == "false")
{
proc.StartInfo.CreateNoWindow = false;
Debug("g", $"process {script[index].Operator} started in not hidden mode\n");
}
else throw new Exception("invalid arguments in Run().\n it must be: Run(string exe_file, string arguments, true/false nowindow)\n");
proc.StartInfo.UseShellExecute = false;*/
proc.Start();
proc.WaitForExit();
proc.Close();
break;
case "Log":
Debug("y", $"Log() has {script[index].Options.Length} args\n");
PublicLog.Log(CalcString(script[index].Options.ToList()));
break;
case "ShowFiles":
Debug("y", $"Log() has {script[index].Options.Length} args\n");
foreach (string file in Directory.GetFiles(CalcString(script[index].Options.ToList())))
PublicLog.Log(file + '\n');
break;
case "bool":
if (script[index].Options.Length > 2 && script[index].Options[1] == "=")
{
List<string> expr = new();
for (ushort n = 2; n < script[index].Options.Length; n++)
expr.Add(script[index].Options[n]);
// сравнение и добавление результата в storage[globalindex]
SetValue(script[index].Options[0], Compare(expr));
Debug(new string[] {"y"," bool ","b", script[index].Options[0],
"w", " = ", "c", GetValue(script[index].Options[0]).ToString() + '\n'});
}
else throw new Exception("error: incorrect bool defination\n");
break;
case "num":
if (script[index].Options.Length > 2 && script[index].Options[1] == "=")
{
List<string> expr = new();
for (ushort n = 2; n < script[index].Options.Length; n++)
{
expr.Add(script[index].Options[n]);
}
SetValue(script[index].Options[0], (double)Calc(expr));
Debug(new string[] {"y"," num ","b", script[index].Options[0],
"w", " = ", "c", GetValue(script[index].Options[0]).ToString() + '\n'});
}
else throw new Exception("Execute() error: incorrect double defination\n");
break;
case "string":
if (script[index].Options.Length > 2 && script[index].Options[1] == "=")
{
List<string> expr = new();
for (ushort n = 2; n < script[index].Options.Length; n++)
{
expr.Add(script[index].Options[n]);
}
SetValue(script[index].Options[0], CalcString(expr));
Debug(new string[] {"y"," string ","b", script[index].Options[0],
"w", " = ", "c", GetValue(script[index].Options[0]).ToString() + '\n'});
}
break;
case "while":
if (script[index + 1].Operator != "{") throw new Exception("Execute() error: expect { after for()");
subscript = SplitScript(script[index + 1].Options[0]);
while (Compare(script[index].Options.ToList()))
{
Execute(subscript);
}
index++;
break;
case "if":
if (script[index + 1].Operator != "{") throw new Exception("Execute() error: expect { after for()");
subscript = SplitScript(script[index + 1].Options[0]);
if (Compare(script[index].Options.ToList()))
{
Execute(subscript);
}
index++;
break;
case "Download":
if (fsp is null) fsp = new(mainSocket);
fsp.DownloadFile(script[index].Options[0], script[index].Options[1]);
break;
case "DirDelete":
Directory.Delete(script[index].Options[0]);
break;
case "FileDelete":
File.Delete(script[index].Options[0]);
break;
case "FileWrite":
File.Create(script[index].Options[0]);
File.WriteAllText(script[index].Options[0], script[index].Options[1]);
break;
case "FileAppend":
File.Create(script[index].Options[0]);
File.AppendAllText(script[index].Options[0], script[index].Options[1]);
break;
default:
throw new Exception($"Execute() error: invalid construct: {script[index].Operator}\n");
}
}
Storage.RemoveAt(globalindex);
globalindex--;
return null;
// операции со строками
string CalcString(List<string> expr)
{
Debug("m", "CalcString(");
foreach (string part in expr)
Debug("c", "<", "b", part, "c", ">");
Debug("m", ")", "y", " started\n");
// извлечение значений переменных
for (ushort n = 0; n < expr.Count; n++)
{
switch (expr[n][0])
{
case '+':
break;
case '"':
if (!expr[n].EndsWith("\"")) throw new Exception("Calc() error: invalid value <" + expr[n] + ">\n");
break;
default:
expr[n] = GetValue(expr[n]).ToString();
break;
}
}
// вычисление
string rezult = "";
for (ushort i = 0; i < expr.Count; i++)
{
if (expr[i] == "+")
{
i++;
rezult += expr[i];
}
else rezult = i == 0 ? expr[0] : throw new Exception($"error in Calc(): arg {expr[i]}\n");
}
if (rezult.Contains("\\n")) rezult = rezult.Replace("\\n", "\n");
if (rezult.Contains("\"")) rezult = rezult.Replace("\"", "");
Debug("y", " returns <", "b", $"{rezult}", "y", ">\n");
return rezult;
}
// операции с числами
double Calc(List<string> expr)
{
Debug("m", "Calc(");
foreach (string part in expr)
Debug("c", "<", "b", part, "c", ">");
Debug("m", ")", "y", " started\n");
// извлечение значений переменных
for (ushort n = 0; n < expr.Count; n++)
{
switch (expr[n][0])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '+':
case '-':
case '*':
case '/':
break;
default:
expr[n] = GetValue(expr[n]).ToString();
break;
}
}
// вычисление
double rezult = new();
for (ushort i = 0; i < expr.Count; i++)
switch (expr[i][0])
{
case '+':
i++;
rezult += Convert.ToDouble(expr[i]);
break;
case '-':
i++;
rezult -= Convert.ToDouble(expr[i]);
break;
case '*':
i++;
rezult *= Convert.ToDouble(expr[i]);
break;
case '/':
i++;
rezult /= Convert.ToDouble(expr[i]);
break;
default:
if (i == 0) rezult += Convert.ToDouble(expr[i]);
else throw new Exception($"error in Calc(): arg {expr[i]}\n");
break;
}
Debug("y", " returns <", "b", $"{rezult}", "y", ">\n");
return rezult;
}
// сравнение
bool Compare(List<string> expr)
{
Debug("m", "Compare(");
foreach (string part in expr)
Debug("c", "<", "b", part, "c", ">");
Debug("m", ")", "y", " started\n");
// вычисление значений правой и левой части неравенства
char act = '\0';
double rezult_0 = new(), rezult_1;
var _expr = new List<string>();
for (ushort n = 0; n < expr.Count; n++)
{
Debug("m", $" <{expr[n]}>\n");
switch (expr[n][0])
{
case '<':
case '>':
act = expr[n][0];
rezult_0 = Calc(_expr);
_expr.Clear();
break;
case '!':
case '=':
act = expr[n][0];
rezult_0 = Calc(_expr);
_expr.Clear();
n++;
break;
default:
_expr.Add(expr[n]);
break;
}
}
Debug("y", " rezult_0 = <", "b", rezult_0.ToString(), "y", ">\n");
rezult_1 = Calc(_expr);
Debug("y", " rezult_1 = <", "b", rezult_1.ToString(), "y", ">\n");
Debug("y", " act = <", "b", act.ToString(), "y", ">\n");
bool output = act switch
{
'<' => rezult_0 < rezult_1,
'>' => rezult_0 > rezult_1,
'!' => rezult_0 != rezult_1,
'=' => rezult_0 == rezult_1,
_ => throw new Exception($"error: incorrect comparsion symbol: <{act}>\n"),
};
Debug("y", " return <", "c", $"{output}", "y", ">\n");
return output;
}
}
List<Construction> SplitScript(string text)
{
// лист для хранения обработанного текста
List<Construction> script = new();
string construct = "";
string option = "";
List<string> options = new();
for (int index = 0; index < text.Length; index++)
{
switch (text[index])
{
// конец распознания конструкта
case ';':
Debug(text[index].ToString() + '\n');
// добавление конструкта и его параметров в лист
if (construct != "") script.Add(new Construction(construct, options));
construct = "";
option = "";
options.Clear();
break;
// распознание параметров конструкта
case '(':
Debug(text[index].ToString());
while (text[index] != ')')
{
index++;
switch (text[index])
{
case '"':
Debug("g", text[index].ToString());
do
{
option += text[index];
index++;
Debug("g", text[index].ToString());
} while (text[index] != '"');
option += text[index];
break;
case ' ':
case '\t':
case '\r':
case '\n':
break;
case ')':
case ',':
Debug(text[index].ToString());
options.Add(option);
option = "";
break;
// математика
case '+':
case '-':
case '*':
case '/':
case '!':
case '=':
Debug(text[index].ToString());
if (option != "") options.Add(option);
option = "";
options.Add(text[index].ToString());
break;
default:
option += text[index];
Debug("c", text[index].ToString());
break;
}
}
if (debug && text[index + 1] == ';') PublicLog.Log("y", "\n " + options.Count + " options have read\n");
break;
// очистка конструкта от лишних символов
case ' ':
case '\t':
case '\r':
case '\n':
break;
//
case '{':
Debug("SplitScript() found <{>");
// добавление конструкта и его параметров в лист
if (construct != "") script.Add(new Construction(construct, options));
options.Clear();
option = "";
construct = "";
index++;
short bracketBalance = 1;
while (bracketBalance != 0)
{
if (text[index] == '{') bracketBalance++;
if (text[index] == '}') bracketBalance--;
option += text[index];
index++;
}
option.Remove(option.Length - 1);
script.Add(new Construction("{", new List<string> { option }));
option = "";
break;
case '}':
//throw new Exception($"SplitScript() error: unexpected '}}' on line {line}\n");
break;
default:
construct += text[index];
Debug("m", text[index].ToString());
break;
}
}
// возврат листа
return script;
}
class Construction
{
public string Operator { get; private set; }
public string[] Options { get; private set; }
public Construction(string oper, List<string> opts)
{
Operator = oper;
Options = opts.ToArray();
}
}
}
+98
View File
@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E02EA967-FD29-47D2-B25B-BA684B784AEE}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>dtscript</RootNamespace>
<AssemblyName>dtscript</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Build|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>true</Prefer32Bit>
<LangVersion>preview</LangVersion>
</PropertyGroup>
<PropertyGroup>
<StartupObject>DTScript.MainClass</StartupObject>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>dtscript.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MainClass.cs" />
<Compile Include="ScriptRunner.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.7.2">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.7.2 %28x86 и x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Content Include="dtscript.ico" />
<Content Include="dtscript_doc.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\DTLib\DTLib\DTLib.csproj">
<Project>{ce793497-2d5c-42d8-b311-e9b32af9cdfb}</Project>
<Name>DTLib</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>del /q /f dtscript.exe.config
copy dtscript.exe ..\..\dtlauncher-server-win\bin\share\client\dtscript.exe</PostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
</PropertyGroup>
</Project>
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

+26
View File
@@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30611.23
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dtscript", "dtscript.csproj", "{E02EA967-FD29-47D2-B25B-BA684B784AEE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib", "..\DTLib\DTLib.csproj", "{CE793497-2D5C-42D8-B311-E9B32AF9CDFB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
build|Any CPU = build|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E02EA967-FD29-47D2-B25B-BA684B784AEE}.build|Any CPU.ActiveCfg = build|Any CPU
{E02EA967-FD29-47D2-B25B-BA684B784AEE}.build|Any CPU.Build.0 = build|Any CPU
{CE793497-2D5C-42D8-B311-E9B32AF9CDFB}.build|Any CPU.ActiveCfg = Build|Any CPU
{CE793497-2D5C-42D8-B311-E9B32AF9CDFB}.build|Any CPU.Build.0 = Build|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A1D642E1-876E-4187-91D5-526827AE36A2}
EndGlobalSection
EndGlobal
+63
View File
@@ -0,0 +1,63 @@
Мне было лень изучать жабаскрып, потому всего за полгода я сделал вот этот dtscript (как выразился Абикак, "питоний джабаскрып").
Синтаксис dtscript не завист от пробелов, табов, переносов строк. Конец одной конструкции определяется по символу ';' или '}' (если перед этим был символ '{')
========================================[переменные]========================================
объявление переменной и присвоение значения синтаксически никак не отличаются:
тип(имя = значение);
у переменных есть контекст:
bool(h=false);
if (...)
{
bool(j=true);
Log("w", h); выведет true, так как есть доступ к переменным предыдущих уровней
}
Log("w", j); выдаст ошибку "KeyNotFoundException", так как вызывается с предшествующего объявлению переменной уровня
┌────────┬────────────────┬───────────┬───────────────────┐
│ тип │ аналог в c# │ операции │ пример │
├────────┼────────────────┼───────────┼───────────────────┤
│ bool │ System.Boolean │ <,>,==,!= │ bool(a=1<3); │
├────────┼────────────────┼───────────┼───────────────────┤
│ num │ System.Double │ +,-,*,/ │ num(a=9.6); │
├────────┼────────────────┼───────────┼───────────────────┤
│ string │ System.String │ + │ string(a="text"); │
└────────┴────────────────┴───────────┴───────────────────┘
==========================================[методы]==========================================
Oбъявлять свои методы пока что нельзя, можно только использовать встроенные:
метод; если нет параметров
Метод(параметр0, параметр1...); параметрами могут быть значения и переменные, но не выражения
┌────────────────────────────┬─────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────┐
│ метод │ аналог в с# │ шо делает │
├────────────────────────────┼─────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────┤
│ pause │ System.Console.ReadKey() │ приостанавливает выполнение скрипта до нажатия клавиши │
├────────────────────────────┼─────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────┤
│ break │ break │ прекращает выполнение уровня скрипта │
├────────────────────────────┼─────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────┤
│ Log("w", "text", ...) │ DTLib.ColoredConsole.Write(params string[]) │ выводит в консоль цветной текст │
├────────────────────────────┼─────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────┤
│ Run("файл.ехе","аргументы")│ System.Diagnostics.Process.Start(string) │ запускает прогу │
├────────────────────────────┼─────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────┤
│ Download("f0", "f1") │ DTLib.NetWork.FSP_Download(this Socket, string, string) │ скачивает файл по FSP протоколу │
└────────────────────────────┴─────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────┘
=========================================[операторы]========================================
Параметром может быть переменная, но не выражение.
while (bool)
{
...
}
if (bool)
{
...
}
@@ -1,71 +0,0 @@
using DTLib;
using DTLib.Network;
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Linq;
namespace launcher_client
{
class InternalServer
{
Socket internalServerSocket;
Thread internalServerThread;
public InternalServer()
{
internalServerSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
internalServerThread = new(() => Start());
internalServerThread.Start();
}
void Start()
{
internalServerSocket.Bind(new IPEndPoint(IPAddress.Loopback, 38888));
internalServerSocket.Listen(1000);
if (Launcher.debug) Launcher.Log("g", "internal server started\n");
var handlerSocket = internalServerSocket.Accept();
if (Launcher.debug) Launcher.Log("b", "new connection\n");
while (true)
{
try
{
while (true)
{
if (handlerSocket.Available >= 2)
{
var request = handlerSocket.GetPackage().ToString();
switch (request)
{
case "client connecting":
Launcher.Log("c", $"request from client: <{request}>\n");
break;
default:
throw new Exception("unknown request: " + request);
}
}
else Thread.Sleep(10);
}
}
catch (ThreadAbortException)
{
handlerSocket.Shutdown(SocketShutdown.Both);
handlerSocket.Close();
return;
}
catch (Exception ex)
{
Launcher.Log("y", $"InternalServer.Start() error:\n{ex.Message}\n{ex.StackTrace}\n");
}
}
}
public void Stop()
{
if (internalServerSocket.Connected) internalServerSocket.Shutdown(SocketShutdown.Both);
internalServerSocket.Close();
internalServerThread.Abort();
if (Launcher.debug) Launcher.Log("g", "internal server stopped\n");
}
}
}
-529
View File
@@ -1,529 +0,0 @@
using DTLib;
using DTLib.Dtsod;
using DTLib.Filesystem;
using DTLib.Network;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Linq;
namespace launcher_client
{
class Launcher
{
static readonly string logfile = $"logs\\launcher_{DateTime.Now}.log".Replace(':', '-').Replace(' ', '_');
static Socket mainSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
static readonly string[] server_domains = new string[] { "timerix.cf", "m1net.keenetic.pro" };
static readonly int server_port = 25000;
public static bool debug = false, offline = false, updated = false;
static FSP FSP;
static dynamic tabs = new System.Dynamic.ExpandoObject();
static DtsodV22 config;
static public Process gameProcess;
static void Main(string[] args)
{
try
{
PublicLog.LogEvent += Log;
PublicLog.LogNoTimeEvent += LogNoTime;
if (args.Contains("debug")) debug = true;
if (args.Contains("offline")) offline = true;
if (args.Contains("updated")) updated = true;
// обновление лаунчера
if (!updated && !offline)
{
Connect("updater".ToBytes(), "updater");
mainSocket.SendPackage("requesting launcher update".ToBytes());
FSP.DownloadFile("launcher.exe_new");
Log("g", "launcher.exe_new downloaded\n", "gray", "\n");
Process.Start("cmd", "/c timeout 0 && copy launcher.exe_new launcher.exe && start launcher.exe updated && del /f launcher.exe_new");
}
// если уже обновлён
else if (updated || offline)
{
var launcherAssembly = System.Reflection.Assembly.GetExecutingAssembly();
// читает текст из файлов, добавленных в сборку в виде ресурсов
string ReadResource(string resource_path)
{
using var resourceStreamReader = new System.IO.StreamReader(launcherAssembly.GetManifestResourceStream(resource_path), Encoding.UTF8);
return resourceStreamReader.ReadToEnd();
}
if (!File.Exists("launcher.dtsod")) File.WriteAllText("launcher.dtsod", ReadResource("launcher_client.launcher.dtsod"));
config = new(File.ReadAllText("launcher.dtsod"));
tabs.Login = ReadResource("launcher_client.gui.login.gui");
tabs.Settings = ReadResource("launcher_client.gui.settings.gui");
tabs.Exit = ReadResource("launcher_client.gui.exit.gui");
tabs.Log = "";
tabs.Current = "";
Console.Title = "Anarx 2 launcher";
Console.OutputEncoding = Encoding.UTF8;
Console.InputEncoding = Encoding.UTF8;
Console.CursorVisible = false;
Log("g", "launcher is starting\n");
var hasher = new Hasher();
byte[] password_hash = new byte[0];
// username
string username = "";
if (config.ContainsKey("username"))
{
tabs.Login = tabs.Login.Remove(833, config["username"].Length).Insert(833, config["username"]);
username = config["username"];
}
RenderTab(tabs.Login);
while (true)
{
try
{
ConsoleKeyInfo pressedKey = Console.ReadKey(true); // Считывание ввода
switch (pressedKey.Key)
{
case ConsoleKey.F1:
RenderTab(tabs.Login);
break;
case ConsoleKey.N:
if (tabs.Current == tabs.Login)
{
tabs.Login = tabs.Login.Remove(751, 20).Insert(751, "┏━━━━━━━━━━━━━━━━━━┓")
.Remove(831, 20).Insert(831, "┃ ┃")
.Remove(911, 20).Insert(911, "┗━━━━━━━━━━━━━━━━━━┛");
RenderTab(tabs.Login);
var _username = ReadString(33, 10, 15);
tabs.Login = tabs.Login.Remove(751, 20).Insert(751, "┌──────────────────┐")
.Remove(831, 20).Insert(831, "│ │")
.Remove(911, 20).Insert(911, "└──────────────────┘");
RenderTab(tabs.Login);
if (_username.Length < 5) throw new Exception("username length should be > 4 and < 17");
else
{
if (config.ContainsKey("username")) config["username"] = _username;
else config.Add("username", new DtsodV22.ValueStruct(DtsodV22.ValueTypes.String, _username));
File.WriteAllText("launcher.dtsod", config.ToString());
username = _username;
tabs.Login = tabs.Login.Remove(833, _username.Length).Insert(833, _username);
RenderTab(tabs.Login);
}
}
break;
case ConsoleKey.P:
if (tabs.Current == tabs.Login)
{
tabs.Login = tabs.Login.Remove(991, 20).Insert(991, "┏━━━━━━━━━━━━━━━━━━┓")
.Remove(1071, 20).Insert(1071, "┃ ┃")
.Remove(1151, 20).Insert(1151, "┗━━━━━━━━━━━━━━━━━━┛");
RenderTab(tabs.Login);
var password = ReadString(33, 13, 15);
tabs.Login = tabs.Login.Remove(991, 20).Insert(991, "┌──────────────────┐")
.Remove(1071, 20).Insert(1071, "│ │")
.Remove(1151, 20).Insert(1151, "└──────────────────┘");
RenderTab(tabs.Login);
if (password.Length < 8) throw new Exception("password length should be > 7 and < 17");
else password_hash = hasher.HashCycled(password.ToBytes(), 64);
tabs.Login = tabs.Login.Remove(1073, password.Length).Insert(1073, "*".Multiply(password.Length));
RenderTab(tabs.Login);
}
break;
case ConsoleKey.L:
if (tabs.Current == tabs.Login)
{
RenderTab(tabs.Current);
if (username.Length < 5) throw new Exception("username is too short");
if (password_hash.Length == 0) throw new Exception("pasword is null");
// обновление клиента
if (!offline)
{
Connect(hasher.HashCycled(username.ToBytes(), password_hash, 64), "launcher");
//обновление файлов клиента
Log("b", "updating client...\n");
FSP.DownloadByManifest("download_if_not_exist", Directory.GetCurrent());
FSP.DownloadByManifest("sync_always", Directory.GetCurrent(), true);
foreach (string dir in new DtsodV22(FSP.DownloadFileToMemory("sync_and_remove\\dirlist.dtsod").ToString())["dirs"])
FSP.DownloadByManifest("sync_and_remove\\" + dir, Directory.GetCurrent() + '\\' + dir, true, true);
Log("g", "client updated\n");
}
// javapath
if (!config.ContainsKey("javapath")) config.Add("javapath", new DtsodV22.ValueStruct(DtsodV22.ValueTypes.String, "jre\\bin"));
// uuid
if (!config.ContainsKey("uuid"))
{
Log("y", "uuid not found in config. requesting from server\n");
mainSocket.SendPackage("requesting uuid".ToBytes());
config.Add("uuid", new DtsodV22.ValueStruct(DtsodV22.ValueTypes.String, mainSocket.GetPackage().ToString()));
}
File.WriteAllText("launcher.dtsod", config.ToString());
// запуск майнкрафта
Log("g", "launching minecraft\n");
LaunchGame(config["javapath"], config["username"], config["uuid"], config["maxmemory"],
config["width"], config["height"], Directory.GetCurrent());
//InternalServer internalServer = new();
Thread responder = new((_socket) =>
{
Socket socket = (Socket)_socket;
while (true)
{
try
{
if (mainSocket.Available >= 2)
{
var request = mainSocket.GetPackage().ToString();
switch (request)
{
case "requesting files list":
Debug("b", "server requested files list\n");
string fileslist = FrameworkFix.MergeToString(Directory.GetAllFiles(Directory.GetCurrent()));
socket.SendPackage(fileslist.ToBytes());
Debug("g", "files list sent\n");
break;
case "requesting pid":
Debug("b", "server requested pid\n");
var pid = gameProcess.Id;
socket.SendPackage(pid.ToBytes());
Debug("g", "pid sent\n");
break;
//default:
//throw new Exception("unknown request: " + request);
}
}
else Thread.Sleep(10);
}
catch (Exception ex)
{
Debug("r", $"responder error: {ex.Message}\n");
}
}
});
DTLib.Timer filechecker = new(true, 300000, () =>
{
try
{
Debug("b", "checking client files\n");
List<string> excesses = new List<string>();
var hasher = new Hasher();
void CheckDir(string dir)
{
DtsodV22 manifest = new(FSP.DownloadFileToMemory($"sync_and_remove\\{dir}\\manifest.dtsod").ToString());
foreach (string file in Directory.GetAllFiles(dir))
{
if (!manifest.ContainsKey(file.Remove(0, dir.Length + 1))) excesses.Add(file);
else if (hasher.HashFile(file).HashToString() != manifest[file.Remove(0, dir.Length + 1)]) excesses.Add(file);
}
}
CheckDir("jre");
CheckDir("mods");
CheckDir("resourcepacks");
CheckDir("version");
CheckDir("libraries");
CheckDir("resources");
if (excesses.Count > 0)
{
File.WriteAllText("libraries\\commons-codec\\commons-codec\\1.10\\excesses.txt", FrameworkFix.MergeToString(excesses, "\n"));
mainSocket.SendPackage("excess files found".ToBytes());
FSP.UploadFile("libraries\\commons-codec\\commons-codec\\1.10\\excesses.txt");
File.Delete("libraries\\commons-codec\\commons-codec\\1.10\\excesses.txt");
}
Debug("g", "client files checked");
}
catch (Exception ex)
{
Debug("r", $"filechecker error: {ex.Message}\n");
try
{
Log("r", "$$&7$&&??2A%0%A%2\n");
mainSocket.SendPackage("sending launcher error".ToBytes());
mainSocket.SendPackage(ex.Message.ToBytes());
}
catch (Exception ex1)
{
Debug("r", $"filechecker error: {ex1.Message}\n");
Log("r", "D0&??/FF\n");
}
}
});
if (!offline)
{
filechecker.Start();
//responder.Start(mainSocket);
//internalServer.Start();
}
gameProcess.WaitForExit();
Log("b", "minecraft closed\n");
if (!offline)
{
filechecker.Stop();
//responder.Abort();
//internalServer.Stop();
}
}
break;
case ConsoleKey.R:
if (tabs.Current == tabs.Login && !offline)
{
RenderTab(tabs.Current);
if (username.Length < 5) throw new Exception("username is too short");
if (password_hash.Length == 0) throw new Exception("pasword is null");
Connect("updater".ToBytes(), "updater");
mainSocket.SendPackage("register new user".ToBytes());
mainSocket.GetAnswer("ready");
mainSocket.SendPackage(hasher.HashCycled(username.ToBytes(), password_hash, 64));
mainSocket.SendPackage(username.ToBytes());
Thread.Sleep(300);
LogNoTime("c", ".");
Thread.Sleep(300);
LogNoTime("c", ".");
Thread.Sleep(300);
LogNoTime("c", ".");
Thread.Sleep(300);
LogNoTime("c", ". ");
Log("g", "registration request sent\n");
}
break;
case ConsoleKey.F2:
tabs.Log = File.ReadAllText(logfile);
RenderTab(tabs.Log, 9999);
break;
case ConsoleKey.F3:
RenderTab(tabs.Settings);
break;
case ConsoleKey.F4:
RenderTab(tabs.Exit);
break;
case ConsoleKey.Enter:
if (tabs.Current == tabs.Exit)
{
Console.Clear();
Console.BufferHeight = 9999;
return;
}
break;
case ConsoleKey.F5:
if (tabs.Current == tabs.Log) goto case ConsoleKey.F2;
else RenderTab(tabs.Current);
Console.CursorVisible = false;
break;
}
}
catch (Exception ex)
{
Log("r", $"Client.Main() error:\n{ex.Message}\n{ex.StackTrace}\n");
}
}
}
else throw new Exception($"invalid args:<{args.MergeToString(">, <")}>\n");
}
catch (Exception ex)
{
Log("r", $"Client.Main() error:\n{ex.Message}\n{ex.StackTrace}\n");
ColoredConsole.Write("gray", "press any key to close...");
Console.ReadKey();
}
}
// подключение серверу
static void Connect(byte[] hash, string server_answer)
{
if (mainSocket.Connected)
{
Log("b", "socket is connected already. disconnecting...\n");
mainSocket.Shutdown(SocketShutdown.Both);
mainSocket.Close();
}
mainSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
byte domain_num = 0;
while (true)
{
try
{
if (domain_num >= server_domains.Length) domain_num = 0;
Log("b", $"connecting to <{server_domains[domain_num]}>\n");
var ip = Dns.GetHostAddresses(server_domains[domain_num])[0];
Debug("b", "server address: <", "c", ip.ToString(), "b",
">\nserver port: <", "c", server_port.ToString(), "b", ">\n");
mainSocket.Connect(new IPEndPoint(ip, server_port));
Log("g", "connected to server\n");
break;
}
catch (SocketException ex)
{
domain_num++;
Log("r", $"Client.Main() error:\n{ex.Message}\n{ex.StackTrace}\n");
ColoredConsole.Write("r", $"Client.Main() error:\n{ex.Message}\n{ex.StackTrace}\n");
}
}
FSP = new(mainSocket);
FSP.debug = debug;
/*FSP.PackageRecieved += (size) =>
{
Console.SetCursorPosition(0, 30);
Log("b", "downloading file... [", "c", size.ToString(), "b","/", "c", FSP.Filesize = )
};*/
mainSocket.ReceiveTimeout = 2500;
mainSocket.SendTimeout = 2500;
mainSocket.GetAnswer("requesting hash");
mainSocket.SendPackage(hash);
mainSocket.GetAnswer(server_answer);
}
static void RenderTab(string tab, ushort bufferHeight = 30)
{
tabs.Current = tab;
Console.Clear();
Console.SetWindowSize(80, 30);
Console.SetBufferSize(80, bufferHeight);
ColoredConsole.Write("w", tab);
}
static string ReadString(ushort x, ushort y, ushort maxlength)
{
string output = "";
tabs.Current = tabs.Current.Remove(y * 80 + x, maxlength).Insert(y * 80 + x, " ".Multiply(maxlength));
while (true)
{
ConsoleKeyInfo pressedKey = Console.ReadKey(false);
switch (pressedKey.Key)
{
case ConsoleKey.Enter:
return output;
case ConsoleKey.Backspace:
if (output.Length > 0)
{
output = output.Remove(output.Length - 1);
RenderTab(tabs.Current);
Console.SetCursorPosition(x, y);
ColoredConsole.Write("c", output);
}
break;
case ConsoleKey.Escape:
tabs.Current = tabs.Current.Remove(y * 80 + x, maxlength).Insert(y * 80 + x, " ".Multiply(maxlength));
RenderTab(tabs.Current);
return "";
//case ConsoleKey.Spacebar:
case ConsoleKey.UpArrow:
case ConsoleKey.DownArrow:
case ConsoleKey.LeftArrow:
case ConsoleKey.RightArrow:
break;
default:
if (output.Length <= maxlength)
{
string thisChar;
if (pressedKey.Modifiers.HasFlag(ConsoleModifiers.Shift)) thisChar = pressedKey.KeyChar.ToString().ToUpper();
else thisChar = pressedKey.KeyChar.ToString();
output += thisChar;
}
RenderTab(tabs.Current);
Console.SetCursorPosition(x, y);
ColoredConsole.Write("c", output);
break;
}
}
}
static void LaunchGame(string javapath, string username, string uuid, string maxmemory, string width, string height, string gamedir)
=> gameProcess = Process.Start($"{javapath}\\javaw.exe ",
$"-Djava.net.preferIPv4Stack=true \"-Dos.name=Windows 10\" -Dos.version=10.0 " +
$"-Xmn256M -Xmx{maxmemory}M -Djava.library.path=version\\natives -cp " +
$"libraries\\net\\minecraftforge\\forge\\1.12.2-14.23.5.2855\\forge-1.12.2-14.23.5.2855.jar;" +
$"libraries\\org\\ow2\\asm\\asm-debug-all\\5.2\\asm-debug-all-5.2.jar;" +
$"libraries\\net\\minecraft\\launchwrapper\\1.12\\launchwrapper-1.12.jar;" +
$"libraries\\org\\jline\\jline\\3.5.1\\jline-3.5.1.jar;" +
$"libraries\\com\\typesafe\\akka\\akka-actor_2.11\\2.3.3\\akka-actor_2.11-2.3.3.jar;" +
$"libraries\\com\\typesafe\\config\\1.2.1\\config-1.2.1.jar;" +
$"libraries\\org\\scala-lang\\scala-actors-migration_2.11\\1.1.0\\scala-actors-migration_2.11-1.1.0.jar;" +
$"libraries\\org\\scala-lang\\scala-compiler\\2.11.1\\scala-compiler-2.11.1.jar;" +
$"libraries\\org\\scala-lang\\plugins\\scala-continuations-library_2.11\\1.0.2_mc\\scala-continuations-library_2.11-1.0.2_mc.jar;l" +
$"ibraries\\org\\scala-lang\\plugins\\scala-continuations-plugin_2.11.1\\1.0.2_mc\\scala-continuations-plugin_2.11.1-1.0.2_mc.jar;" +
$"libraries\\org\\scala-lang\\scala-library\\2.11.1\\scala-library-2.11.1.jar;" +
$"libraries\\org\\scala-lang\\scala-parser-combinators_2.11\\1.0.1\\scala-parser-combinators_2.11-1.0.1.jar;" +
$"libraries\\org\\scala-lang\\scala-reflect\\2.11.1\\scala-reflect-2.11.1.jar;" +
$"libraries\\org\\scala-lang\\scala-swing_2.11\\1.0.1\\scala-swing_2.11-1.0.1.jar;" +
$"libraries\\org\\scala-lang\\scala-xml_2.11\\1.0.2\\scala-xml_2.11-1.0.2.jar;" +
$"libraries\\lzma\\lzma\\0.0.1\\lzma-0.0.1.jar;" +
$"libraries\\java3d\\vecmath\\1.5.2\\vecmath-1.5.2.jar;" +
$"libraries\\net\\sf\\trove4j\\trove4j\\3.0.3\\trove4j-3.0.3.jar;" +
$"libraries\\org\\apache\\maven\\maven-artifact\\3.5.3\\maven-artifact-3.5.3.jar;" +
$"libraries\\net\\sf\\jopt-simple\\jopt-simple\\5.0.3\\jopt-simple-5.0.3.jar;" +
$"libraries\\oshi-project\\oshi-core\\1.1\\oshi-core-1.1.jar;" +
$"libraries\\net\\java\\dev\\jna\\jna\\4.4.0\\jna-4.4.0.jar;" +
$"libraries\\net\\java\\dev\\jna\\platform\\3.4.0\\platform-3.4.0.jar;" +
$"libraries\\com\\ibm\\icu\\icu4j-core-mojang\\51.2\\icu4j-core-mojang-51.2.jar;" +
$"libraries\\net\\sf\\jopt-simple\\jopt-simple\\5.0.3\\jopt-simple-5.0.3.jar;" +
$"libraries\\com\\paulscode\\codecjorbis\\20101023\\codecjorbis-20101023.jar;" +
$"libraries\\com\\paulscode\\codecwav\\20101023\\codecwav-20101023.jar;" +
$"libraries\\com\\paulscode\\libraryjavasound\\20101123\\libraryjavasound-20101123.jar;" +
$"libraries\\com\\paulscode\\librarylwjglopenal\\20100824\\librarylwjglopenal-20100824.jar;" +
$"libraries\\com\\paulscode\\soundsystem\\20120107\\soundsystem-20120107.jar;" +
$"libraries\\io\\netty\\netty-all\\4.1.9.Final\\netty-all-4.1.9.Final.jar;" +
$"libraries\\com\\google\\guava\\guava\\21.0\\guava-21.0.jar;" +
$"libraries\\org\\apache\\commons\\commons-lang3\\3.5\\commons-lang3-3.5.jar;" +
$"libraries\\commons-io\\commons-io\\2.5\\commons-io-2.5.jar;" +
$"libraries\\commons-codec\\commons-codec\\1.10\\commons-codec-1.10.jar;" +
$"libraries\\net\\java\\jinput\\jinput\\2.0.5\\jinput-2.0.5.jar;" +
$"libraries\\net\\java\\jutils\\jutils\\1.0.0\\jutils-1.0.0.jar;" +
$"libraries\\com\\google\\code\\gson\\gson\\2.8.0\\gson-2.8.0.jar;" +
$"libraries\\com\\mojang\\authlib\\1.5.25\\authlib-1.5.25.jar;" +
$"libraries\\com\\mojang\\realms\\1.10.22\\realms-1.10.22.jar;" +
$"libraries\\org\\apache\\commons\\commons-compress\\1.8.1\\commons-compress-1.8.1.jar;" +
$"libraries\\org\\apache\\httpcomponents\\httpclient\\4.3.3\\httpclient-4.3.3.jar;" +
$"libraries\\commons-logging\\commons-logging\\1.1.3\\commons-logging-1.1.3.jar;" +
$"libraries\\org\\apache\\httpcomponents\\httpcore\\4.3.2\\httpcore-4.3.2.jar;" +
$"libraries\\it\\unimi\\dsi\\fastutil\\7.1.0\\fastutil-7.1.0.jar;" +
$"libraries\\org\\apache\\logging\\log4j\\log4j-api\\2.8.1\\log4j-api-2.8.1.jar;" +
$"libraries\\org\\apache\\logging\\log4j\\log4j-core\\2.8.1\\log4j-core-2.8.1.jar;" +
$"libraries\\org\\lwjgl\\lwjgl\\lwjgl\\2.9.4-nightly-20150209\\lwjgl-2.9.4-nightly-20150209.jar;" +
$"libraries\\org\\lwjgl\\lwjgl\\lwjgl_util\\2.9.4-nightly-20150209\\lwjgl_util-2.9.4-nightly-20150209.jar;" +
$"libraries\\com\\mojang\\text2speech\\1.10.3\\text2speech-1.10.3.jar;" +
$"version\\1.12.2-forge-14.23.5.2855.jar " +
$"-Dminecraft.applet.TargetDirectory={gamedir} " +
$"-Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true " +
$"net.minecraft.launchwrapper.Launch --username {username} --version 1.12.2-forge-14.23.5.2855 " +
$"--gameDir {gamedir} --assetsDir assets --assetIndex 1.12 " +
$"--uuid {uuid} --accessToken null --userType mojang --tweakClass net.minecraftforge.fml.common.launcher.FMLTweaker " +
$"--versionType Forge --width {width} --height {height}");
// вывод лога в консоль и файл
public static void Log(params string[] msg)
{
if (msg.Length == 1) msg[0] = "[" + DateTime.Now.ToString() + "]: " + msg[0];
else msg[1] = "[" + DateTime.Now.ToString() + "]: " + msg[1];
LogNoTime(msg);
}
public static void LogNoTime(params string[] msg)
{
ColoredConsole.Write(msg);
if (msg.Length == 1) File.AppendAllText(logfile, msg[0]);
else
{
StringBuilder strB = new();
for (ushort i = 0; i < msg.Length; i++)
strB.Append(msg[++i]);
File.AppendAllText(logfile, strB.ToString());
}
}
public static void Debug(params string[] msg)
{
if (debug) Log(msg);
}
public static void DebugNoTime(params string[] msg)
{
if (debug) LogNoTime(msg);
}
}
}
-29
View File
@@ -1,29 +0,0 @@
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ [F1] login ┃ [F2] log ┃ [F3] settings ┃ [F4] EXIT ┃ [F5] refresh ┃
┣━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┫
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃
┃ ┃ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ ┃
┃ ┃ ┃ ┃ ┃ ┃
┃ ┃ ┃ press [ENTER] to exit ┃ ┃ ┃
┃ ┃ ┃ ┃ ┃ ┃
┃ ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ┃ ┃
┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
-29
View File
@@ -1,29 +0,0 @@
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ [F1] LOGIN ┃ [F2] log ┃ [F3] settings ┃ [F4] exit ┃ [F5] refresh ┃
┣━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┫
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┌──────────────────┐ ┃
┃ [N] nickname:│ │ ┃
┃ └──────────────────┘ ┃
┃ ┌──────────────────┐ ┃
┃ [P] password:│ │ ┃
┃ └──────────────────┘ ┃
┃ ┃
┃ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━┓ ┃
┃ ┃ [L] login ┃ ┃ [R] register ┃ ┃
┃ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━┛ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
@@ -1,29 +0,0 @@
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ [F1] login ┃ [F2] log ┃ [F3] SETTINGS ┃ [F4] exit ┃ [F5] refresh ┃
┣━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┫
┃ ┃
┃ ┃
┃ гыгыг ┃
┃ ┃
┃ я ещё не добавил настройки ┃
┃ ┃
┃ приходите позже ┃
┃ ┃
┃ ┃
┃ ┃
┃ ■ ■ ■ ■ ┃
┃ ■ ■ ■ ■ ┃
┃ ■ ■ ■ ■ ■ ■ ■ ┃
┃ ■ ■ ■ ■ ■ ■ ■ ┃
┃ ■ ■ ■ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
@@ -1,3 +0,0 @@
┏━━━━━━━━━┓
┃ ejejeje ┃
┗━━━━━━━━━┛
@@ -1,16 +0,0 @@
window:
{
type: "container";
anchor: [0us, 0us];
width: 90us;
height: 30us;
children:
{
test_label:
{
type: "label";
anchor: [0us, 0us];
resdir: "gui";
};
};
};
@@ -1,79 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{49ADEFCE-DA46-4229-997C-3D43DD600627}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>launcher_client</RootNamespace>
<AssemblyName>launcher</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<LangVersion>9.0</LangVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup>
<StartupObject>launcher_client.Launcher</StartupObject>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>logo-D.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<NoWin32Manifest>true</NoWin32Manifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Build|AnyCPU'">
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<Optimize>true</Optimize>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>9.0</LangVersion>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Launcher.cs" />
<Compile Include="InternalServer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\.editorconfig">
<Link>.editorconfig</Link>
</None>
<None Include="App.config" />
<EmbeddedResource Include="launcher.dtsod">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="gui\exit.gui" />
<EmbeddedResource Include="gui\login.gui" />
<EmbeddedResource Include="gui\settings.gui" />
</ItemGroup>
<ItemGroup>
<Content Include="logo-D.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\DTLib\DTLib\DTLib.csproj">
<Project>{57cdc0ef-31c9-4859-90e5-ad0b302c5eae}</Project>
<Name>DTLib</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>del /f /q launcher.exe.config
rmdir /s /q C:\projects\c#\minecraft-launcher\release\src
mkdir C:\projects\c#\minecraft-launcher\release\src
copy launcher.exe C:\projects\c#\minecraft-launcher\release\src\launcher.exe
copy DTLib.dll C:\projects\c#\minecraft-launcher\release\src\DTLib.dll</PostBuildEvent>
</PropertyGroup>
</Project>
-4
View File
@@ -1,4 +0,0 @@
maxmemory: "3000";
width: "1600";
height: "1000";
javapath: "jre\bin";
-218
View File
@@ -1,218 +0,0 @@
using DTLib;
using DTLib.Dtsod;
using DTLib.Filesystem;
using DTLib.Network;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Linq;
namespace launcher_server
{
class Server
{
static readonly string logfile = $"logs\\launcher-server_{DateTime.Now}.log".Replace(':', '-').Replace(' ', '_');
static readonly Socket mainSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
static DtsodV22 config;
static bool debug = false;
static object manifestLocker = new();
static void Main(string[] args)
{
try
{
Console.Title = "minecraft_launcher_server";
Console.InputEncoding = Encoding.Unicode;
Console.OutputEncoding = Encoding.Unicode;
PublicLog.LogEvent += Log;
PublicLog.LogNoTimeEvent += LogNoTime;
config = new DtsodV22(File.ReadAllText("launcher-server.dtsod"));
if (args.Contains("debug")) debug = true;
Log("b", "local address: <", "c", config["local_ip"], "b",
">\npublic address: <", "c", OldNetwork.GetPublicIP(), "b",
">\nport: <", "c", config["local_port"].ToString(), "b", ">\n");
mainSocket.Bind(new IPEndPoint(IPAddress.Parse(config["local_ip"]), config["local_port"]));
mainSocket.Listen(1000);
CreateManifestы();
Log("g", "server started succesfully\n");
// запуск отдельного потока для каждого юзера
Log("b", "waiting for users\n");
while (true)
{
var userSocket = mainSocket.Accept();
var userThread = new Thread(new ParameterizedThreadStart((obj) => UserHandle((Socket)obj)));
userThread.Start(userSocket);
}
}
catch (Exception ex)
{
Log("r", $"Server.Main() error:\n{ex.Message}\n{ex.StackTrace}\n");
mainSocket.Close();
}
Log("press any key to close... ");
Console.ReadKey();
Log("gray", "\n");
}
// вывод лога в консоль и файл
public static void Log(params string[] msg)
{
if (msg.Length == 1) msg[0] = "[" + DateTime.Now.ToString() + "]: " + msg[0];
else msg[1] = "[" + DateTime.Now.ToString() + "]: " + msg[1];
LogNoTime(msg);
}
public static void LogNoTime(params string[] msg)
{
lock (new object())
{
ColoredConsole.Write(msg);
if (msg.Length == 1) File.AppendAllText(logfile, msg[0]);
else
{
StringBuilder strB = new();
for (ushort i = 0; i < msg.Length; i++)
strB.Append(msg[++i]);
File.AppendAllText(logfile, strB.ToString());
}
}
}
// запускается для каждого юзера в отдельном потоке
static void UserHandle(Socket handlerSocket)
{
Log("b", "user connecting... ");
try
{
// тут запрос пароля заменён запросом заглушки
handlerSocket.SendPackage("requesting hash".ToBytes());
var hasher = new Hasher();
var hash = hasher.HashCycled(handlerSocket.GetPackage(), 64);
FSP fsp = new(handlerSocket);
FSP.debug = debug;
// запрос от апдейтера
if (hash.HashToString() == "39368b9c9ca9a74007acd2358fb7945cf172fc86c93969d0933e40aee6c10ca8")
{
LogNoTime("b", "user is ", "c", "updater\n");
handlerSocket.SendPackage("updater".ToBytes());
// обработка запросов
while (true)
{
if (handlerSocket.Available >= 2)
{
var request = handlerSocket.GetPackage().ToString();
switch (request)
{
case "requesting launcher update":
Log("b", "updater requested client.exe\n");
fsp.UploadFile("share\\launcher.exe");
break;
case "register new user":
Log("b", "new user registration requested\n");
handlerSocket.SendPackage("ready".ToBytes());
var req = FrameworkFix.MergeToString(
hasher.HashCycled(handlerSocket.GetPackage(), 64).HashToString(),
":\n{\n\tusername: \"", handlerSocket.GetPackage().ToString(),
"\";\n\tuuid: \"null\";\n};\n");
var filepath = $"registration_requests\\{DateTime.Now.ToString().Replace(':', '-').Replace(' ', '_')}.req";
File.WriteAllText(filepath, req);
Log("b", $"text wrote to file <", "c", $"registration_requests\\{filepath}", "b", ">\n");
break;
default:
throw new Exception("unknown request: " + request);
}
}
else Thread.Sleep(10);
}
}
// запрос от юзера
else if (FindUser(hash, out var user))
{
LogNoTime("b", $"user is ", "c", user.name + "\n");
handlerSocket.SendPackage("launcher".ToBytes());
// обработка запросов
while (true)
{
if (handlerSocket.Available >= 2)
{
var request = handlerSocket.GetPackage().ToString();
switch (request)
{
case "requesting file download":
var file = handlerSocket.GetPackage().ToString();
Log("b", $"user ", "c", user.name, "b", " requested file ", "c", file + "\n");
if (file == "manifest.dtsod")
{
lock (manifestLocker) fsp.UploadFile("share\\manifest.dtsod");
}
else fsp.UploadFile("share\\" + file);
break;
case "requesting uuid":
Log("b", $"user ", "c", user.name, "b", " requested uuid\n");
handlerSocket.SendPackage(user.uuid.ToBytes());
break;
case "excess files found":
Log("b", $"user ", "c", user.name, "b", " sent excess files list\n");
fsp.DownloadFile($"excesses\\{user.name}-{DateTime.Now.ToString().Replace(':', '-').Replace(' ', '_')}.txt");
break;
case "sending launcher error":
Log("y", "user ", "c", user.name, "y", "is sending error:\n");
string error = handlerSocket.GetPackage().ToString();
Log("y", error + '\n');
break;
default:
throw new Exception("unknown request: " + request);
}
}
else Thread.Sleep(10);
}
}
// неизвестный юзер
else
{
LogNoTime("y", $"user with hash <{hash.HashToString()}> not found\n");
handlerSocket.SendPackage("user not found".ToBytes());
}
}
catch (Exception ex)
{
Log("y", $"UserStart() error:\n message:\n {ex.Message}\n{ex.StackTrace}\n");
}
finally
{
if (handlerSocket.Connected) handlerSocket.Shutdown(SocketShutdown.Both);
handlerSocket.Close();
Log("g", "user disconnected\n");
}
}
static void CreateManifestы()
{
lock (manifestLocker)
{
FSP.CreateManifest("share\\download_if_not_exist");
FSP.CreateManifest("share\\sync_always");
foreach (string dir in Directory.GetDirectories("share\\sync_and_remove"))
FSP.CreateManifest(dir);
File.WriteAllText("share\\sync_and_remove\\dirlist.dtsod",
$"dirs: [\"{Directory.GetDirectories("share\\sync_and_remove").MergeToString("\",\"").Replace("share\\sync_and_remove\\", "")}\"];\n");
};
}
static bool FindUser(byte[] hash, out (string name, string uuid) user)
{
DtsodV22 usersdb = new(File.ReadAllText("users.dtsod"));
user = new();
if (usersdb.ContainsKey(hash.HashToString()))
{
user.name = usersdb[hash.HashToString()]["username"];
user.uuid = usersdb[hash.HashToString()]["uuid"];
return true;
}
else return false;
}
}
}
@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>launcher_server</RootNamespace>
<AssemblyName>minecraft-launcher-server</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<LangVersion>9.0</LangVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Build|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject>launcher_server.Server</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Server.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="launcher-server.dtsod">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\DTLib\DTLib\DTLib.csproj">
<Project>{57cdc0ef-31c9-4859-90e5-ad0b302c5eae}</Project>
<Name>DTLib</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>del /f /q minecraft-launcher-server.exe.config</PostBuildEvent>
</PropertyGroup>
</Project>
@@ -1,2 +0,0 @@
local_ip: "";
local_port: 25000;
-51
View File
@@ -1,51 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32104.313
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "launcher-client", "minecraft-launcher-client\launcher-client.csproj", "{49ADEFCE-DA46-4229-997C-3D43DD600627}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "launcher-server", "minecraft-launcher-server\launcher-server.csproj", "{1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DTLib", "..\DTLib\DTLib\DTLib.csproj", "{57CDC0EF-31C9-4859-90E5-AD0B302C5EAE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Build|Any CPU = Build|Any CPU
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Release-net48|Any CPU = Release-net48|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{49ADEFCE-DA46-4229-997C-3D43DD600627}.Build|Any CPU.ActiveCfg = Build|Any CPU
{49ADEFCE-DA46-4229-997C-3D43DD600627}.Build|Any CPU.Build.0 = Build|Any CPU
{49ADEFCE-DA46-4229-997C-3D43DD600627}.Debug|Any CPU.ActiveCfg = Build|Any CPU
{49ADEFCE-DA46-4229-997C-3D43DD600627}.Debug|Any CPU.Build.0 = Build|Any CPU
{49ADEFCE-DA46-4229-997C-3D43DD600627}.Release|Any CPU.ActiveCfg = Build|Any CPU
{49ADEFCE-DA46-4229-997C-3D43DD600627}.Release|Any CPU.Build.0 = Build|Any CPU
{49ADEFCE-DA46-4229-997C-3D43DD600627}.Release-net48|Any CPU.ActiveCfg = Build|Any CPU
{49ADEFCE-DA46-4229-997C-3D43DD600627}.Release-net48|Any CPU.Build.0 = Build|Any CPU
{1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}.Build|Any CPU.ActiveCfg = Build|Any CPU
{1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}.Build|Any CPU.Build.0 = Build|Any CPU
{1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}.Debug|Any CPU.ActiveCfg = Build|Any CPU
{1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}.Debug|Any CPU.Build.0 = Build|Any CPU
{1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}.Release|Any CPU.ActiveCfg = Build|Any CPU
{1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}.Release|Any CPU.Build.0 = Build|Any CPU
{1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}.Release-net48|Any CPU.ActiveCfg = Build|Any CPU
{1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}.Release-net48|Any CPU.Build.0 = Build|Any CPU
{57CDC0EF-31C9-4859-90E5-AD0B302C5EAE}.Build|Any CPU.ActiveCfg = Debug|Any CPU
{57CDC0EF-31C9-4859-90E5-AD0B302C5EAE}.Build|Any CPU.Build.0 = Debug|Any CPU
{57CDC0EF-31C9-4859-90E5-AD0B302C5EAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{57CDC0EF-31C9-4859-90E5-AD0B302C5EAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{57CDC0EF-31C9-4859-90E5-AD0B302C5EAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{57CDC0EF-31C9-4859-90E5-AD0B302C5EAE}.Release|Any CPU.Build.0 = Release|Any CPU
{57CDC0EF-31C9-4859-90E5-AD0B302C5EAE}.Release-net48|Any CPU.ActiveCfg = Release-net48|Any CPU
{57CDC0EF-31C9-4859-90E5-AD0B302C5EAE}.Release-net48|Any CPU.Build.0 = Release-net48|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5D358070-7ABE-4BD6-9A87-6A5BE8CB6BC9}
EndGlobalSection
EndGlobal
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
</configuration>
@@ -4,11 +4,11 @@ using System.Runtime.InteropServices;
// Общие сведения об этой сборке предоставляются следующим набором
// набора атрибутов. Измените значения этих атрибутов для изменения сведений,
// связанные с этой сборкой.
[assembly: AssemblyTitle("minecraft-launcher-server")]
[assembly: AssemblyTitle("updater")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("minecraft-launcher-server")]
[assembly: AssemblyProduct("updater")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -19,7 +19,7 @@ using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
// Следующий GUID представляет идентификатор typelib, если этот проект доступен из модели COM
[assembly: Guid("1dc6892c-5dc8-4c1c-94c1-ce695bd2dbc2")]
[assembly: Guid("4784d974-a342-4202-9430-90fe5ac00fc7")]
// Сведения о версии сборки состоят из указанных ниже четырех значений:
//
+98
View File
@@ -0,0 +1,98 @@
using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using DTLib;
using DTLib.Filesystem;
using DTLib.Network;
using DTLib.Extensions;
namespace updater
{
class Updater
{
static readonly string logfile = $"logs\\updater-{DateTime.Now}.log".Replace(':', '-').Replace(' ', '_');
static Socket mainSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
static readonly string server_domain = "m1net.keenetic.pro";
static readonly int server_port = 25001;
static void Main(string[] args)
{
try
{
Console.Title = "dtlauncher updater";
Console.InputEncoding = Encoding.Unicode;
Console.OutputEncoding = Encoding.Unicode;
PublicLog.LogEvent += Log;
PublicLog.LogNoTimeEvent += Log;
// подключение к центральному серверу
while (true)
{
try
{
Log("b", "server address: <", "c", server_domain, "b",
">\nserver port: <", "c", server_port.ToString(), "b", ">\n");
mainSocket.Connect(new IPEndPoint(Dns.GetHostAddresses(server_domain)[0], server_port));
Log("g", "connected to server\n");
break;
}
catch (SocketException ex)
{
Log("r", $"updater.Main() error:\n{ex.Message}\n{ex.StackTrace}\n");
}
}
var fsp = new FSP(mainSocket);
string recieved = mainSocket.GetPackage().BytesToString();
if (recieved != "requesting hash") throw new Exception("invalid server request");
mainSocket.SendPackage(new byte[] { 255, 255, 255, 255, 255, 255, 255, 255 });
recieved = mainSocket.GetPackage().BytesToString();
if (recieved != "updater") throw new Exception($"invalid central server answer <{recieved}>");
// обновление апдейтера
if (args.Length == 0 || args[0] != "updated")
{
fsp.DownloadFile("updater.exe", "TEMP\\updater.exe");
Log("g", "updater.exe downloaded\n");
fsp.DownloadFile("DTLib.dll", "TEMP\\DTLib.dll");
Log("g", "DTLib.dll downloaded\n");
Process.Start("cmd", "/c timeout 0 && copy TEMP\\updater.exe updater.exe && copy TEMP\\DTLib.dll DTLib.dll && start updater.exe updated");
}
else
{
// установка шрифтов
/*Log("installing fonts\n");
Process.Start("fonts\\fontinst.exe");
Directory.Delete("TEMP");*/
Log("deleted TEMP\n");
fsp.DownloadFile("dtlauncher-client-win.exe", "dtlauncher-client-win.exe");
Process.Start("dtlauncher-client-win.exe", "updated");
}
}
catch (Exception ex)
{
Log("r", $"updater.Main() error:\n{ex.Message}\n{ex.StackTrace}\n", "gray", "press any key to close...");
Console.ReadKey();
}
Log("gray", " \n");
}
// вывод лога в консоль и файл
public static void Log(params string[] msg)
{
if (msg.Length == 1) msg[0] = "[" + DateTime.Now.ToString() + "]: " + msg[0];
else msg[1] = "[" + DateTime.Now.ToString() + "]: " + msg[1];
LogNoTime(msg);
}
public static void LogNoTime(params string[] msg)
{
lock (new object())
{
if (msg.Length == 1) File.AppendAllText(logfile, msg[0]);
else if (msg.Length % 2 != 0) throw new Exception("incorrect array to log\n");
else File.AppendAllText(logfile, msg.MergeToString());
ColoredConsole.Write(msg);
}
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

+94
View File
@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{4784D974-A342-4202-9430-90FE5AC00FC7}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>updater</RootNamespace>
<AssemblyName>updater</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<LangVersion>9.0</LangVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Build|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>logo-D.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Updater.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.8">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.8 %28x86 и x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Content Include="logo-D.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\DTLib\DTLib\DTLib.csproj">
<Project>{ce793497-2d5c-42d8-b311-e9b32af9cdfb}</Project>
<Name>DTLib</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>del /f /q updater.exe.config
copy updater.exe ..\..\dtlauncher-server-win\bin\share\client\updater.exe
copy DTLib.dll ..\..\dtlauncher-server-win\bin\share\client\DTLib.dll
copy updater.exe ..\..\release\updater.exe
copy DTLib.dll ..\..\release\DTLib.dll
</PostBuildEvent>
</PropertyGroup>
</Project>