Compare commits

...

12 Commits

126 changed files with 75658 additions and 354 deletions

1
.gitignore vendored
View File

@ -6,3 +6,4 @@
/AxibugEmuOnline.Client/*.sln
/AxibugEmuOnline.Client/*.sln
/AxibugEmuOnline.Client/ProjectSettings/Packages/
/AxibugEmuOnline.Web/config.cfg

View File

@ -5,91 +5,91 @@ namespace MyNes.Core
{
public class INes : IRom
{
public bool HasBattery { get; private set; }
public bool HasBattery { get; private set; }
public bool IsPlaychoice10 { get; private set; }
public bool IsPlaychoice10 { get; private set; }
public bool IsVSUnisystem { get; private set; }
public bool IsVSUnisystem { get; private set; }
public override void Load(string fileName, bool loadDumps)
{
FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
if (fileStream.Length < 16)
{
fileStream.Close();
base.IsValid = false;
return;
}
byte[] array = new byte[16];
fileStream.Read(array, 0, 16);
byte[] buffer = new byte[fileStream.Length - 16];
fileStream.Read(buffer, 0, (int)(fileStream.Length - 16));
base.SHA1 = "";
byte[] array2 = new SHA1Managed().ComputeHash(buffer);
foreach (byte b in array2)
{
base.SHA1 += b.ToString("x2").ToLower();
}
if (array[0] != 78 || array[1] != 69 || array[2] != 83 || array[3] != 26)
{
fileStream.Close();
base.IsValid = false;
return;
}
base.PRGCount = array[4];
base.CHRCount = array[5];
switch (array[6] & 9)
{
case 0:
base.Mirroring = Mirroring.Horz;
break;
case 1:
base.Mirroring = Mirroring.Vert;
break;
case 8:
case 9:
base.Mirroring = Mirroring.Full;
break;
}
HasBattery = (array[6] & 2) != 0;
base.HasTrainer = (array[6] & 4) != 0;
if ((array[7] & 0xF) == 0)
{
base.MapperNumber = (byte)((array[7] & 0xF0) | (array[6] >> 4));
}
else
{
base.MapperNumber = (byte)(array[6] >> 4);
}
IsVSUnisystem = (array[7] & 1) != 0;
IsPlaychoice10 = (array[7] & 2) != 0;
if (loadDumps)
{
fileStream.Seek(16L, SeekOrigin.Begin);
if (base.HasTrainer)
{
base.Trainer = new byte[512];
fileStream.Read(base.Trainer, 0, 512);
}
else
{
base.Trainer = new byte[0];
}
base.PRG = new byte[base.PRGCount * 16384];
fileStream.Read(base.PRG, 0, base.PRGCount * 16384);
if (base.CHRCount > 0)
{
base.CHR = new byte[base.CHRCount * 8192];
fileStream.Read(base.CHR, 0, base.CHRCount * 8192);
}
else
{
base.CHR = new byte[0];
}
}
base.IsValid = true;
fileStream.Dispose();
fileStream.Close();
}
public override void Load(string fileName, bool loadDumps)
{
var fileStream = MyNesMain.FileManager.OpenRomFile(fileName);
if (fileStream.Length < 16)
{
fileStream.Close();
base.IsValid = false;
return;
}
byte[] array = new byte[16];
fileStream.Read(array, 0, 16);
byte[] buffer = new byte[fileStream.Length - 16];
fileStream.Read(buffer, 0, (int)(fileStream.Length - 16));
base.SHA1 = "";
byte[] array2 = new SHA1Managed().ComputeHash(buffer);
foreach (byte b in array2)
{
base.SHA1 += b.ToString("x2").ToLower();
}
if (array[0] != 78 || array[1] != 69 || array[2] != 83 || array[3] != 26)
{
fileStream.Close();
base.IsValid = false;
return;
}
base.PRGCount = array[4];
base.CHRCount = array[5];
switch (array[6] & 9)
{
case 0:
base.Mirroring = Mirroring.Horz;
break;
case 1:
base.Mirroring = Mirroring.Vert;
break;
case 8:
case 9:
base.Mirroring = Mirroring.Full;
break;
}
HasBattery = (array[6] & 2) != 0;
base.HasTrainer = (array[6] & 4) != 0;
if ((array[7] & 0xF) == 0)
{
base.MapperNumber = (byte)((array[7] & 0xF0) | (array[6] >> 4));
}
else
{
base.MapperNumber = (byte)(array[6] >> 4);
}
IsVSUnisystem = (array[7] & 1) != 0;
IsPlaychoice10 = (array[7] & 2) != 0;
if (loadDumps)
{
fileStream.Seek(16L, SeekOrigin.Begin);
if (base.HasTrainer)
{
base.Trainer = new byte[512];
fileStream.Read(base.Trainer, 0, 512);
}
else
{
base.Trainer = new byte[0];
}
base.PRG = new byte[base.PRGCount * 16384];
fileStream.Read(base.PRG, 0, base.PRGCount * 16384);
if (base.CHRCount > 0)
{
base.CHR = new byte[base.CHRCount * 8192];
fileStream.Read(base.CHR, 0, base.CHRCount * 8192);
}
else
{
base.CHR = new byte[0];
}
}
base.IsValid = true;
fileStream.Dispose();
fileStream.Close();
}
}
}

View File

@ -218,5 +218,6 @@ namespace MyNes.Core
string GetWorkingFolderPath();
public Stream OpenDatabaseFile();
public Stream OpenPaletteFile();
public Stream OpenRomFile(string path);
}
}

View File

@ -5141,47 +5141,39 @@ namespace MyNes.Core
success = false;
return;
}
string text = Path.GetExtension(fileName).ToLower();
if (text != null && text == ".nes")
Tracer.WriteLine("Checking INES header ...");
INes nes = new INes();
nes.Load(fileName, loadDumps: true);
if (nes.IsValid)
{
Tracer.WriteLine("Checking INES header ...");
INes nes = new INes();
nes.Load(fileName, loadDumps: true);
if (nes.IsValid)
emu_request_mode = RequestMode.None;
CurrentFilePath = fileName;
if (ON)
{
emu_request_mode = RequestMode.None;
CurrentFilePath = fileName;
if (ON)
{
ShutDown();
}
Tracer.WriteLine("INES header is valid, loading game ...");
ApplyRegionSetting();
MEMInitialize(nes);
ApplyAudioSettings();
ApplyFrameSkipSettings();
ApplyPaletteSetting();
PORTSInitialize();
hardReset();
Tracer.WriteLine("EMU is ready.");
success = true;
emu_frame_clocking_mode = !useThread;
ON = true;
PAUSED = false;
if (useThread)
{
Tracer.WriteLine("Running in a thread ... using custom frame limiter.");
FrameLimiterEnabled = true;
mainThread = new Thread(EmuClock);
mainThread.Start();
}
MyNesMain.VideoProvider.SignalToggle(started: true);
MyNesMain.AudioProvider.SignalToggle(started: true);
ShutDown();
}
else
Tracer.WriteLine("INES header is valid, loading game ...");
ApplyRegionSetting();
MEMInitialize(nes);
ApplyAudioSettings();
ApplyFrameSkipSettings();
ApplyPaletteSetting();
PORTSInitialize();
hardReset();
Tracer.WriteLine("EMU is ready.");
success = true;
emu_frame_clocking_mode = !useThread;
ON = true;
PAUSED = false;
if (useThread)
{
success = false;
Tracer.WriteLine("Running in a thread ... using custom frame limiter.");
FrameLimiterEnabled = true;
mainThread = new Thread(EmuClock);
mainThread.Start();
}
MyNesMain.VideoProvider.SignalToggle(started: true);
MyNesMain.AudioProvider.SignalToggle(started: true);
}
else
{
@ -5298,6 +5290,16 @@ namespace MyNes.Core
}
}
public static void ExecuteOneFrame()
{
while (!ppu_frame_finished)
{
CPUClock();
}
FrameFinished();
}
private static void EmuClock()
{
while (ON)

View File

@ -11,13 +11,13 @@ namespace MyNes.Core
public static void WriteLine(string message)
{
Tracer.EventRaised?.Invoke(null, new TracerEventArgs(message, TracerStatus.Normal));
Debug.Log(message);
//Debug.Log(message);
}
public static void WriteLine(string message, string category)
{
Tracer.EventRaised?.Invoke(null, new TracerEventArgs($"{category}: {message}", TracerStatus.Normal));
Debug.Log(message);
//Debug.Log(message);
}
public static void WriteLine(string message, TracerStatus status)
@ -28,10 +28,10 @@ namespace MyNes.Core
case TracerStatus.Error: Debug.LogError(message); break;
case TracerStatus.Infromation:
case TracerStatus.Normal:
Debug.Log(message);
//Debug.Log(message);
break;
case TracerStatus.Warning:
Debug.LogWarning(message);
//Debug.LogWarning(message);
break;
}

View File

@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 4664d2ef3d138e141b308c242abd4327
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,6 @@
fileFormatVersion: 2
guid: dee4e4661b99068439cc932db923d849
guid: ac852e7a0b9604940b0f7e0180fd2707
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 040fea71e1812ce45bd2b72c8ad2e2ae
guid: 01dd757415143ae46921461228964dd5
TextScriptImporter:
externalObjects: {}
userData:

View File

@ -1,6 +1,6 @@
fileFormatVersion: 2
guid: 23a003aef20e19f4d8c45acd32012718
DefaultImporter:
guid: ecb5d904338d35c43bb3b98249b36394
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:

View File

@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 5df1a0f25b9a1864493e694ce7b40cc4
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 333f6913aec8b2b41807add4cf643f6a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -169,57 +169,6 @@ MonoBehaviour:
m_EditorClassIdentifier:
VideoCom: {fileID: 730321753}
AudioCom: {fileID: 1379369700}
--- !u!1 &455467288
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 455467291}
- component: {fileID: 455467290}
m_Layer: 0
m_Name: GameObject
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &455467290
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 455467288}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 00080631f10e2834db28c37a11188a74, type: 3}
m_Name:
m_EditorClassIdentifier:
sampleRate: 44100
channels: 2
bufferLength: 1024
audioClip: {fileID: 0}
audioSource: {fileID: 0}
audioBuffer: []
isRunning: 1
--- !u!4 &455467291
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 455467288}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 253.16292, y: 149.09415, z: -2.2723875}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &708549044
GameObject:
m_ObjectHideFlags: 0
@ -314,6 +263,85 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &723385291
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 723385292}
- component: {fileID: 723385294}
- component: {fileID: 723385293}
m_Layer: 5
m_Name: fps
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &723385292
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 723385291}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 730321749}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 160, y: 30}
m_Pivot: {x: 1, y: 0}
--- !u!114 &723385293
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 723385291}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 14
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 8
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 1
m_VerticalOverflow: 1
m_LineSpacing: 1
m_Text:
--- !u!222 &723385294
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 723385291}
m_CullTransparentMesh: 1
--- !u!1 &730321748
GameObject:
m_ObjectHideFlags: 0
@ -324,7 +352,6 @@ GameObject:
m_Component:
- component: {fileID: 730321749}
- component: {fileID: 730321752}
- component: {fileID: 730321751}
- component: {fileID: 730321753}
m_Layer: 5
m_Name: video
@ -332,7 +359,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
m_IsActive: 1
--- !u!224 &730321749
RectTransform:
m_ObjectHideFlags: 0
@ -342,9 +369,11 @@ RectTransform:
m_GameObject: {fileID: 730321748}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: -1, z: 1}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Children:
- {fileID: 2100984176}
- {fileID: 723385292}
m_Father: {fileID: 786008058}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
@ -352,33 +381,6 @@ RectTransform:
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &730321751
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 730321748}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Texture: {fileID: 0}
m_UVRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
--- !u!222 &730321752
CanvasRenderer:
m_ObjectHideFlags: 0
@ -399,7 +401,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: f2632911774df3c488ec24b39651c4de, type: 3}
m_Name:
m_EditorClassIdentifier:
m_image: {fileID: 730321751}
m_drawCanvas: {fileID: 2100984177}
m_fpsText: {fileID: 723385293}
--- !u!1 &786008057
GameObject:
m_ObjectHideFlags: 0
@ -809,6 +812,78 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_as: {fileID: 1379369699}
--- !u!1 &2100984175
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2100984176}
- component: {fileID: 2100984178}
- component: {fileID: 2100984177}
m_Layer: 5
m_Name: canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!224 &2100984176
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2100984175}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: -1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 730321749}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &2100984177
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2100984175}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Texture: {fileID: 0}
m_UVRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
--- !u!222 &2100984178
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2100984175}
m_CullTransparentMesh: 1
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
@ -817,4 +892,3 @@ SceneRoots:
- {fileID: 708549046}
- {fileID: 258485947}
- {fileID: 1359344834}
- {fileID: 455467291}

View File

@ -1,5 +1,7 @@
using MyNes.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using UnityEngine;
@ -20,8 +22,10 @@ namespace AxibugEmuOnline.Client
[SerializeField]
private AudioSource m_as;
private Stopwatch sw = Stopwatch.StartNew();
private Queue<short> _buffer = new Queue<short>(2048);
private Queue<short> _buffer = new Queue<short>();
public double FPS { get; private set; }
public void Initialize()
{
@ -40,25 +44,28 @@ namespace AxibugEmuOnline.Client
int step = channels;
for (int i = 0; i < data.Length; i += step)
{
var rawFloat = _buffer.Count > 0 ? (_buffer.Dequeue() / 124f) : lastData;
var rawFloat = _buffer.Count <= 0 ? lastData : _buffer.Dequeue() / 124f;
data[i] = rawFloat;
for (int fill = 1; fill < step; fill++)
data[i + fill] = rawFloat;
lastData = rawFloat;
}
}
int EmuAudioTimeSample = 0;
private TimeSpan lastElapsed;
public void SubmitSamples(ref short[] buffer, ref int samples_a)
{
EmuAudioTimeSample += samples_a;
var current = sw.Elapsed;
var delta = current - lastElapsed;
lastElapsed = current;
FPS = 1d / delta.TotalSeconds;
for (int i = 0; i < samples_a; i++)
{
_buffer.Enqueue(buffer[i]);
}
}
public void TogglePause(bool paused)

View File

@ -15,17 +15,21 @@ namespace AxibugEmuOnline.Client
public string ID => nameof(UguiVideoProvider).GetHashCode().ToString();
[SerializeField]
private RawImage m_drawCanvas;
[SerializeField]
private Text m_fpsText;
private Color[] m_texRawBuffer = new Color[256 * 240];
private Texture2D m_rawBufferWarper;
[SerializeField]
private RawImage m_image;
private RenderTexture m_drawRT;
private Color temp = Color.white;
public void Initialize()
{
m_rawBufferWarper = new Texture2D(256, 240);
m_image.texture = RenderTexture.GetTemporary(256, 240, 0, UnityEngine.Experimental.Rendering.GraphicsFormat.B8G8R8A8_UNorm);
m_drawCanvas.texture = RenderTexture.GetTemporary(256, 240, 0, UnityEngine.Experimental.Rendering.GraphicsFormat.B8G8R8A8_UNorm);
}
public void GetColor(uint value, ref Color res)
@ -45,7 +49,9 @@ namespace AxibugEmuOnline.Client
var colors = m_texRawBuffer;
m_rawBufferWarper.SetPixels(colors);
m_rawBufferWarper.Apply();
Graphics.Blit(m_rawBufferWarper, m_image.texture as RenderTexture);
Graphics.Blit(m_rawBufferWarper, m_drawCanvas.texture as RenderTexture);
m_fpsText.text = $"Audio:{NesCoreProxy.Instance.AudioCom.FPS}";
}
public void WriteErrorNotification(string message, bool instant)

View File

@ -7,10 +7,15 @@ namespace AxibugEmuOnline.Client.Manager
{
public class AppEmu : IFileManager
{
public void Init(IVideoProvider videoCom,IAudioProvider audioCom)
public void Init(IVideoProvider videoCom, IAudioProvider audioCom)
{
MyNesMain.Initialize(this, videoCom, audioCom);
NesEmu.LoadGame("E:/kirby.nes", out var successed, true);
NesEmu.LoadGame("kirby.nes", out var successed, true);
}
public void ExecuteFrameLogic()
{
//NesEmu.ExecuteOneFrame();
}
public void Dispose()
@ -36,5 +41,12 @@ namespace AxibugEmuOnline.Client.Manager
{
return $"{Application.persistentDataPath}/MyNes";
}
public Stream OpenRomFile(string path)
{
var ta = Resources.Load<TextAsset>($"Roms/{path}");
MemoryStream ms = new MemoryStream(ta.bytes);
return ms;
}
}
}

View File

@ -21,6 +21,11 @@ namespace AxibugEmuOnline.Client
m_appEnum.Init(VideoCom, AudioCom);
}
private void Update()
{
m_appEnum.ExecuteFrameLogic();
}
private void OnDestroy()
{
Instance = null;

View File

@ -657,7 +657,7 @@ PlayerSettings:
embeddedLinuxEnableGamepadInput: 1
hmiLogStartupTiming: 0
hmiCpuConfiguration:
apiCompatibilityLevel: 6
apiCompatibilityLevel: 3
activeInputHandler: 0
windowsGamepadBackendHint: 0
cloudProjectId:

View File

@ -19,7 +19,7 @@ MonoBehaviour:
width: 1920
height: 989
m_ShowMode: 4
m_Title: Console
m_Title: Hierarchy
m_RootView: {fileID: 9}
m_MinSize: {x: 875, y: 300}
m_MaxSize: {x: 10000, y: 10000}
@ -41,7 +41,7 @@ MonoBehaviour:
serializedVersion: 2
x: 0
y: 580
width: 1175
width: 1174
height: 359
m_MinSize: {x: 101, y: 121}
m_MaxSize: {x: 4001, y: 4021}
@ -70,12 +70,12 @@ MonoBehaviour:
serializedVersion: 2
x: 0
y: 0
width: 1175
width: 1174
height: 939
m_MinSize: {x: 100, y: 100}
m_MaxSize: {x: 8096, y: 16192}
vertical: 1
controlID: 16
controlID: 41
--- !u!114 &4
MonoBehaviour:
m_ObjectHideFlags: 52
@ -93,7 +93,7 @@ MonoBehaviour:
serializedVersion: 2
x: 0
y: 579
width: 417
width: 418
height: 360
m_MinSize: {x: 232, y: 271}
m_MaxSize: {x: 10002, y: 10021}
@ -119,14 +119,14 @@ MonoBehaviour:
- {fileID: 4}
m_Position:
serializedVersion: 2
x: 1175
x: 1174
y: 0
width: 417
width: 418
height: 939
m_MinSize: {x: 100, y: 100}
m_MaxSize: {x: 8096, y: 16192}
vertical: 1
controlID: 77
controlID: 100
--- !u!114 &6
MonoBehaviour:
m_ObjectHideFlags: 52
@ -144,10 +144,10 @@ MonoBehaviour:
serializedVersion: 2
x: 0
y: 0
width: 417
width: 418
height: 579
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_MinSize: {x: 202, y: 221}
m_MaxSize: {x: 4002, y: 4021}
m_ActualView: {fileID: 16}
m_Panes:
- {fileID: 16}
@ -177,7 +177,7 @@ MonoBehaviour:
m_MinSize: {x: 300, y: 100}
m_MaxSize: {x: 24288, y: 16192}
vertical: 0
controlID: 140
controlID: 139
--- !u!114 &8
MonoBehaviour:
m_ObjectHideFlags: 52
@ -197,8 +197,8 @@ MonoBehaviour:
y: 0
width: 328
height: 939
m_MinSize: {x: 275, y: 50}
m_MaxSize: {x: 4000, y: 4000}
m_MinSize: {x: 276, y: 71}
m_MaxSize: {x: 4001, y: 4021}
m_ActualView: {fileID: 15}
m_Panes:
- {fileID: 15}
@ -299,7 +299,7 @@ MonoBehaviour:
m_MinSize: {x: 200, y: 100}
m_MaxSize: {x: 16192, y: 16192}
vertical: 0
controlID: 76
controlID: 99
--- !u!114 &13
MonoBehaviour:
m_ObjectHideFlags: 52
@ -317,7 +317,7 @@ MonoBehaviour:
serializedVersion: 2
x: 0
y: 0
width: 1175
width: 1174
height: 580
m_MinSize: {x: 201, y: 221}
m_MaxSize: {x: 4001, y: 4021}
@ -346,9 +346,9 @@ MonoBehaviour:
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 1175
x: 1174
y: 652
width: 415
width: 416
height: 339
m_SerializedDataModeController:
m_DataMode: 0
@ -371,7 +371,7 @@ MonoBehaviour:
m_SkipHidden: 0
m_SearchArea: 1
m_Folders:
- Assets
- Assets/Script/Emu
m_Globs: []
m_OriginalText:
m_ImportLogFlags: 0
@ -379,16 +379,16 @@ MonoBehaviour:
m_ViewMode: 1
m_StartGridSize: 16
m_LastFolders:
- Assets
- Assets/Script/Emu
m_LastFoldersGridSize: 16
m_LastProjectPath: E:\AxibugEmuOnline\AxibugEmuOnline.Client
m_LockTracker:
m_IsLocked: 0
m_FolderTreeState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs: 56410000
m_LastClickedID: 16726
m_ExpandedIDs: 00000000564100006c41000000ca9a3b
m_SelectedIDs: 38610000
m_LastClickedID: 24888
m_ExpandedIDs: 00000000645f0000a25f000000ca9a3b
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
@ -416,7 +416,7 @@ MonoBehaviour:
scrollPos: {x: 0, y: 0}
m_SelectedIDs:
m_LastClickedID: 0
m_ExpandedIDs: 0000000056410000
m_ExpandedIDs: 00000000645f0000
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
@ -443,7 +443,7 @@ MonoBehaviour:
m_ListAreaState:
m_SelectedInstanceIDs:
m_LastClickedInstanceID: 0
m_HadKeyboardFocusLastEvent: 0
m_HadKeyboardFocusLastEvent: 1
m_ExpandedInstanceIDs: c6230000
m_RenameOverlay:
m_UserAcceptedRename: 0
@ -539,9 +539,9 @@ MonoBehaviour:
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 1175
x: 1174
y: 73
width: 415
width: 416
height: 558
m_SerializedDataModeController:
m_DataMode: 0
@ -558,7 +558,7 @@ MonoBehaviour:
scrollPos: {x: 0, y: 0}
m_SelectedIDs:
m_LastClickedID: 0
m_ExpandedIDs: 40fbffff
m_ExpandedIDs: dae5ffff24fbfffffe5e00000a5f0000145f0000
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
@ -604,7 +604,7 @@ MonoBehaviour:
serializedVersion: 2
x: 0
y: 653
width: 1172
width: 1174
height: 338
m_SerializedDataModeController:
m_DataMode: 0
@ -1050,14 +1050,14 @@ MonoBehaviour:
m_OverrideSceneCullingMask: 6917529027641081856
m_SceneIsLit: 1
m_SceneLighting: 1
m_2DMode: 0
m_2DMode: 1
m_isRotationLocked: 0
m_PlayAudio: 0
m_AudioPlay: 0
m_Position:
m_Target: {x: 0, y: 0, z: 0}
m_Target: {x: 253.16292, y: 149.09415, z: -2.2723875}
speed: 2
m_Value: {x: 0, y: 0, z: 0}
m_Value: {x: 253.16292, y: 149.09415, z: -2.2723875}
m_RenderMode: 0
m_CameraMode:
drawMode: 0
@ -1085,17 +1085,17 @@ MonoBehaviour:
m_Size: {x: 0, y: 0}
yGrid:
m_Fade:
m_Target: 1
m_Target: 0
speed: 2
m_Value: 1
m_Value: 0
m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4}
m_Pivot: {x: 0, y: 0, z: 0}
m_Size: {x: 1, y: 1}
zGrid:
m_Fade:
m_Target: 0
m_Target: 1
speed: 2
m_Value: 0
m_Value: 1
m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4}
m_Pivot: {x: 0, y: 0, z: 0}
m_Size: {x: 1, y: 1}
@ -1103,17 +1103,17 @@ MonoBehaviour:
m_GridAxis: 1
m_gridOpacity: 0.5
m_Rotation:
m_Target: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226}
m_Target: {x: 0, y: 0, z: 0, w: 1}
speed: 2
m_Value: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226}
m_Value: {x: 0, y: 0, z: 0, w: 1}
m_Size:
m_Target: 10
m_Target: 260.2281
speed: 2
m_Value: 10
m_Value: 260.2281
m_Ortho:
m_Target: 0
m_Target: 1
speed: 2
m_Value: 0
m_Value: 1
m_CameraSettings:
m_Speed: 1
m_SpeedNormalized: 0.5
@ -1156,7 +1156,7 @@ MonoBehaviour:
serializedVersion: 2
x: 0
y: 73
width: 1174
width: 1173
height: 559
m_SerializedDataModeController:
m_DataMode: 0
@ -1174,7 +1174,7 @@ MonoBehaviour:
m_ShowGizmos: 0
m_TargetDisplay: 0
m_ClearColor: {r: 0, g: 0, b: 0, a: 0}
m_TargetSize: {x: 1174, y: 538}
m_TargetSize: {x: 1173, y: 538}
m_TextureFilterMode: 0
m_TextureHideFlags: 61
m_RenderIMGUI: 1
@ -1189,8 +1189,8 @@ MonoBehaviour:
m_VRangeLocked: 0
hZoomLockedByDefault: 0
vZoomLockedByDefault: 0
m_HBaseRangeMin: -587
m_HBaseRangeMax: 587
m_HBaseRangeMin: -586.5
m_HBaseRangeMax: 586.5
m_VBaseRangeMin: -269
m_VBaseRangeMax: 269
m_HAllowExceedBaseRangeMin: 1
@ -1210,23 +1210,23 @@ MonoBehaviour:
serializedVersion: 2
x: 0
y: 21
width: 1174
width: 1173
height: 538
m_Scale: {x: 1, y: 1}
m_Translation: {x: 587, y: 269}
m_Translation: {x: 586.5, y: 269}
m_MarginLeft: 0
m_MarginRight: 0
m_MarginTop: 0
m_MarginBottom: 0
m_LastShownAreaInsideMargins:
serializedVersion: 2
x: -587
x: -586.5
y: -269
width: 1174
width: 1173
height: 538
m_MinimalGUI: 1
m_defaultScale: 1
m_LastWindowPixelSize: {x: 1174, y: 559}
m_LastWindowPixelSize: {x: 1173, y: 559}
m_ClearInEditMode: 1
m_NoCameraWarning: 1
m_LowResolutionForAspectRatios: 01000001000000000000
@ -1254,7 +1254,7 @@ MonoBehaviour:
serializedVersion: 2
x: 0
y: 653
width: 1174
width: 1173
height: 338
m_SerializedDataModeController:
m_DataMode: 0

View File

@ -1,31 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34511.84
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AxibugEmuOnline.Server", "AxibugEmuOnline.Server\AxibugEmuOnline.Server.csproj", "{38E193D4-3BEC-42D0-9616-53D7AF3937FC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{F151804D-CF60-437E-ACE6-F1C04DCECBF8}"
ProjectSection(SolutionItems) = preProject
..\Lib\Google.Protobuf.dll = ..\Lib\Google.Protobuf.dll
..\Lib\HaoYueNet.ServerNetwork.dll = ..\Lib\HaoYueNet.ServerNetwork.dll
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{38E193D4-3BEC-42D0-9616-53D7AF3937FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38E193D4-3BEC-42D0-9616-53D7AF3937FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38E193D4-3BEC-42D0-9616-53D7AF3937FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38E193D4-3BEC-42D0-9616-53D7AF3937FC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {705EF8E0-A868-4412-BC48-A7DD735C2DBD}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MySql.Data" Version="9.0.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,68 @@
using System.Data;
using System.Text.Encodings.Web;
using System.Text;
using System.Text.Json;
using System.Text.Unicode;
namespace AxibugEmuOnline.Web.Common
{
public class ConfigDataModel
{
public string DBIp{get;set;}
public ushort DBPort{get;set; }
public string DBName { get; set; }
public string DBUname{get;set;}
public string DBPwd{get;set;}
public string RomDir{get;set;}
public string ImageDir { get; set; }
}
public static class Config
{
public static ConfigDataModel cfg;
public static bool LoadConfig()
{
try
{
string path = System.Environment.CurrentDirectory + "//config.cfg";
if (!File.Exists(path))
{
ConfigDataModel sampleCfg = new ConfigDataModel
{
DBIp = "127.0.0.1",
DBPort = 3306,
DBUname = "user",
DBPwd = "password",
DBName = "DBName",
RomDir = "./Rom",
ImageDir = "./Img",
};
string jsonString = JsonSerializer.Serialize(sampleCfg, new JsonSerializerOptions()
{
// 整齐打印
WriteIndented = true,
//重新编码,解决中文乱码问题
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
});
System.IO.File.WriteAllText(path, jsonString, Encoding.UTF8);
Console.WriteLine("未找到配置,已生成模板,请浏览" + path);
return false;
}
StreamReader sr = new StreamReader(path, Encoding.Default);
String jsonstr = sr.ReadToEnd();
cfg = JsonSerializer.Deserialize<ConfigDataModel>(jsonstr);
sr.Close();
return true;
}
catch (Exception ex)
{
Console.WriteLine("配置文件异常:" + ex.ToString());
return false;
}
}
}
}

View File

@ -0,0 +1,179 @@
using Microsoft.Extensions.Logging;
using MySql.Data.MySqlClient;
namespace AxibugEmuOnline.Web.Common
{
public static class Haoyue_SQLPoolManager
{
private static Queue<MySqlConnection> SQLPool = new Queue<MySqlConnection>();
private static Dictionary<MySqlConnection, Haoyue_PoolTime> _OutOfSQLPool = new Dictionary<MySqlConnection, Haoyue_PoolTime>();
private static Dictionary<string, long> _DicSqlRunFunNum = new Dictionary<string, long>();
private static Dictionary<string, long> _DicTimeOutSqlRunFunNum = new Dictionary<string, long>();
private const int DefaultCount = 1;
private const int MaxLimit = 5;
private static readonly object _sync = new object();
private static MySqlConnectionStringBuilder connBuilder;
public static void InitConnMgr()
{
connBuilder = new MySqlConnectionStringBuilder();
connBuilder.Database = Config.cfg.DBName;
connBuilder.Server = Config.cfg.DBIp;
connBuilder.UserID = Config.cfg.DBUname;
connBuilder.Password = Config.cfg.DBPwd;
connBuilder.Port = Config.cfg.DBPort;
//connBuilder.MinimumPoolSize = 40u;
//connBuilder.MaximumPoolSize = 100u;
connBuilder.Pooling = true;
Console.WriteLine("SQLPool连接初始化....");
for (int i = 0; i < DefaultCount; i++)
{
MySqlConnection _conn = conn();
_conn.Open();
SQLPool.Enqueue(_conn);
}
Console.WriteLine("SQLPool初始化完毕,连接数" + SQLPool.Count);
}
public static MySqlConnection conn()
{
return new MySqlConnection(connBuilder.ConnectionString);
}
public static MySqlConnection DequeueSQLConn(string FuncStr)
{
lock (_sync)
{
if (_DicSqlRunFunNum.ContainsKey(FuncStr))
{
_DicSqlRunFunNum[FuncStr]++;
}
else
{
_DicSqlRunFunNum[FuncStr] = 1L;
}
MySqlConnection _conn;
if (SQLPool.Count < 1)
{
Console.WriteLine("[DequeueSQLConn]创建新的SQLPool.Count>" + SQLPool.Count);
_conn = conn();
_conn.Open();
}
else
{
Console.WriteLine("[DequeueSQLConn]取出一个SQLCount.Count>" + SQLPool.Count);
_conn = SQLPool.Dequeue();
}
_OutOfSQLPool.Add(_conn, new Haoyue_PoolTime
{
time = time(),
FuncStr = FuncStr
});
return _conn;
}
}
public static void EnqueueSQLConn(MySqlConnection BackConn)
{
lock (_sync)
{
if (_OutOfSQLPool.ContainsKey(BackConn))
{
_OutOfSQLPool.Remove(BackConn);
}
else
{
Console.WriteLine("出队遗漏的数据出现了!");
}
if (SQLPool.Count > MaxLimit)
{
Console.WriteLine("已经不需要回收了,多余了,SQLPool.Count>" + SQLPool.Count);
BackConn.Close();
BackConn = null;
}
else
{
SQLPool.Enqueue(BackConn);
Console.WriteLine("回收SQLPool.Count>" + SQLPool.Count);
}
}
}
public static void CheckPoolTimeOut()
{
lock (_sync)
{
long now = time();
List<MySqlConnection> removeTemp = new List<MySqlConnection>();
foreach (KeyValuePair<MySqlConnection, Haoyue_PoolTime> o2 in _OutOfSQLPool)
{
if (now - o2.Value.time >= 120)
{
if (_DicTimeOutSqlRunFunNum.ContainsKey(o2.Value.FuncStr))
{
_DicTimeOutSqlRunFunNum[o2.Value.FuncStr]++;
}
else
{
_DicTimeOutSqlRunFunNum[o2.Value.FuncStr] = 1L;
}
if (SQLPool.Count > MaxLimit)
{
Console.WriteLine("[超时回收]" + o2.Value.FuncStr + "已经不需要回收了,多余了,SQLPool.Count>" + SQLPool.Count);
o2.Key.Close();
}
else
{
Console.WriteLine("[超时回收]" + o2.Value.FuncStr + "回收SQLPool.Count>" + SQLPool.Count);
SQLPool.Enqueue(o2.Key);
}
removeTemp.Add(o2.Key);
}
}
if (removeTemp.Count() <= 0)
{
return;
}
foreach (MySqlConnection o in removeTemp)
{
if (_OutOfSQLPool.ContainsKey(o))
{
_OutOfSQLPool.Remove(o);
Console.WriteLine("[超时回收]_OutOfSQLPool清理");
}
else
{
Console.WriteLine("[超时回收]_OutOfSQLPool清理异常");
}
}
Console.WriteLine("[超时回收]处理结束SQLPool.Count>" + SQLPool.Count);
}
}
public static long time()
{
return Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds);
}
public static void GetPoolState()
{
Console.WriteLine("-----------------查询统计-----------------");
foreach (KeyValuePair<string, long> dic2 in _DicSqlRunFunNum)
{
Console.WriteLine(dic2.Key + ":" + dic2.Value);
}
Console.WriteLine("-----------------超时统计-----------------");
foreach (KeyValuePair<string, long> dic in _DicTimeOutSqlRunFunNum)
{
Console.WriteLine(dic.Key + ":" + dic.Value);
}
Console.WriteLine("------------------------------------------");
}
}
public class Haoyue_PoolTime
{
public long time { get; set; }
public string FuncStr { get; set; }
}
}

View File

@ -0,0 +1,86 @@
using AxibugEmuOnline.Web.Common;
using Microsoft.AspNetCore.Mvc;
using MySql.Data.MySqlClient;
namespace AxibugEmuOnline.Web.Controllers
{
public class ApiController : Controller
{
private readonly ILogger<ApiController> _logger;
public ApiController(ILogger<ApiController> logger)
{
_logger = logger;
}
[HttpGet]
public JsonResult NesRomList(string SearchKey,int Page, int PageSize)
{
string searchPattern = $"%{SearchKey}%";
Resp_GameList resp = new Resp_GameList();
resp.GameList = new List<Resp_RomInfo>();
using (MySqlConnection conn = Haoyue_SQLPoolManager.DequeueSQLConn("NesRomList"))
{
string query = "SELECT count(id) FROM romlist_nes where `Name` like ?searchPattern ";
using (var command = new MySqlCommand(query, conn))
{
// 设置参数值
command.Parameters.AddWithValue("?searchPattern", searchPattern);
// 执行查询并处理结果
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
resp.ResultAllCount = reader.GetInt32(0);
resp.Page = Page;
resp.MaxPage = resp.ResultAllCount / PageSize;
}
}
}
query = "SELECT id,`Name`,RomUrl,ImgUrl FROM romlist_nes where `Name` like ?searchPattern LIMIT ?offset, ?pageSize;";
using (var command = new MySqlCommand(query, conn))
{
// 设置参数值
command.Parameters.AddWithValue("?searchPattern", searchPattern);
command.Parameters.AddWithValue("?offset", Page * PageSize);
command.Parameters.AddWithValue("?pageSize", PageSize);
// 执行查询并处理结果
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
resp.GameList.Add(new Resp_RomInfo() {
ID = reader.GetInt32(0),
RomName = reader.GetString(1),
Hash = string.Empty,
ImgUrl = reader.GetString(2),
Url = reader.GetString(3),
});
}
}
}
Haoyue_SQLPoolManager.EnqueueSQLConn(conn);
}
return new JsonResult(resp);
}
class Resp_GameList
{
public int Page { get; set; }
public int MaxPage { get; set; }
public int ResultAllCount { get; set; }
public List<Resp_RomInfo> GameList { get; set; }
}
public class Resp_RomInfo
{
public int ID { get; set; }
public string Hash { get; set; }
public string RomName { get; set;}
public string Url { get; set; }
public string ImgUrl { get; set; }
}
}
}

View File

@ -0,0 +1,32 @@
using AxibugEmuOnline.Web.Models;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
namespace AxibugEmuOnline.Web.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}

View File

@ -0,0 +1,9 @@
namespace AxibugEmuOnline.Web.Models
{
public class ErrorViewModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}

View File

@ -0,0 +1,37 @@
using AxibugEmuOnline.Web.Common;
namespace AxibugEmuOnline.Web
{
public class Program
{
public static void Main(string[] args)
{
Config.LoadConfig();
Haoyue_SQLPoolManager.InitConnMgr();
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
}
}
}

View File

@ -0,0 +1,29 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:27108",
"sslPort": 0
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5051",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,8 @@
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

View File

@ -0,0 +1,6 @@
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>

View File

@ -0,0 +1,25 @@
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>

View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - AxibugEmuOnline.Web</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/AxibugEmuOnline.Web.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">AxibugEmuOnline.Web</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2024 - AxibugEmuOnline.Web - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

View File

@ -0,0 +1,48 @@
/* Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification
for details on configuring this project to bundle and minify static web assets. */
a.navbar-brand {
white-space: normal;
text-align: center;
word-break: break-all;
}
a {
color: #0077cc;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.border-top {
border-top: 1px solid #e5e5e5;
}
.border-bottom {
border-bottom: 1px solid #e5e5e5;
}
.box-shadow {
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
}
button.accept-policy {
font-size: 1rem;
line-height: inherit;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
white-space: nowrap;
line-height: 60px;
}

View File

@ -0,0 +1,2 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

View File

@ -0,0 +1,3 @@
@using AxibugEmuOnline.Web
@using AxibugEmuOnline.Web.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@ -0,0 +1,22 @@
html {
font-size: 14px;
}
@media (min-width: 768px) {
html {
font-size: 16px;
}
}
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}
html {
position: relative;
min-height: 100%;
}
body {
margin-bottom: 60px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,4 @@
// Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification
// for details on configuring this project to bundle and minify static web assets.
// Write your JavaScript code.

View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2011-2021 Twitter, Inc.
Copyright (c) 2011-2021 The Bootstrap Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,427 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
background-color: currentColor;
border: 0;
opacity: 0.25;
}
hr:not([size]) {
height: 1px;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-bs-original-title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-left: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.2em;
background-color: #fcf8e3;
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: #0d6efd;
text-decoration: underline;
}
a:hover {
color: #0a58ca;
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
direction: ltr /* rtl:ignore */;
unicode-bidi: bidi-override;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: #d63384;
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.2rem 0.4rem;
font-size: 0.875em;
color: #fff;
background-color: #212529;
border-radius: 0.2rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
font-weight: 700;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: #6c757d;
text-align: left;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]::-webkit-calendar-picker-indicator {
display: none;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: left;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
font-size: calc(1.275rem + 0.3vw);
line-height: inherit;
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: left;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
outline-offset: -2px;
-webkit-appearance: textfield;
}
/* rtl:raw:
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
*/
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::file-selector-button {
font: inherit;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,424 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
background-color: currentColor;
border: 0;
opacity: 0.25;
}
hr:not([size]) {
height: 1px;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-bs-original-title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-right: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-right: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.2em;
background-color: #fcf8e3;
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: #0d6efd;
text-decoration: underline;
}
a:hover {
color: #0a58ca;
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
direction: ltr ;
unicode-bidi: bidi-override;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: #d63384;
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.2rem 0.4rem;
font-size: 0.875em;
color: #fff;
background-color: #212529;
border-radius: 0.2rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
font-weight: 700;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: #6c757d;
text-align: right;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]::-webkit-calendar-picker-indicator {
display: none;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: right;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
font-size: calc(1.275rem + 0.3vw);
line-height: inherit;
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: right;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
outline-offset: -2px;
-webkit-appearance: textfield;
}
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::file-selector-button {
font: inherit;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-right:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-right:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:right}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:right;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:right}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}[type=email],[type=number],[type=tel],[type=url]{direction:ltr}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.rtl.min.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More