mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-18 12:05:14 -04:00
redesign how file and directory methods work
This commit is contained in:
parent
c68eb4df4b
commit
533cca344f
@ -13,15 +13,13 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
|
|
||||||
public LoadLevelScreen(Game game) : base(game) {
|
public LoadLevelScreen(Game game) : base(game) {
|
||||||
titleText = "Select a level";
|
titleText = "Select a level";
|
||||||
string dir = Path.Combine(Program.AppDirectory, "maps");
|
string[] rawFiles = Platform.DirectoryFiles("maps");
|
||||||
string[] rawFiles = Directory.GetFiles(dir);
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
// Only add map files
|
// Only add map files
|
||||||
for (int i = 0; i < rawFiles.Length; i++) {
|
for (int i = 0; i < rawFiles.Length; i++) {
|
||||||
string file = rawFiles[i];
|
string file = rawFiles[i];
|
||||||
if (file.EndsWith(".cw") || file.EndsWith(".dat")
|
if (file.EndsWith(".cw") || file.EndsWith(".dat") || file.EndsWith(".fcm") || file.EndsWith(".lvl")) {
|
||||||
|| file.EndsWith(".fcm") || file.EndsWith(".lvl")) {
|
|
||||||
count++;
|
count++;
|
||||||
} else {
|
} else {
|
||||||
rawFiles[i] = null;
|
rawFiles[i] = null;
|
||||||
@ -38,13 +36,9 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override void TextButtonClick(Game game, Widget widget) {
|
protected override void TextButtonClick(Game game, Widget widget) {
|
||||||
string path = Path.Combine(Program.AppDirectory, "maps");
|
string path = Path.Combine("maps", ((ButtonWidget)widget).Text);
|
||||||
path = Path.Combine(path, ((ButtonWidget)widget).Text);
|
if (!Platform.FileExists(path)) return;
|
||||||
if (File.Exists(path))
|
|
||||||
LoadMap(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadMap(string path) {
|
|
||||||
IMapFormatImporter importer = null;
|
IMapFormatImporter importer = null;
|
||||||
if (path.EndsWith(".dat")) {
|
if (path.EndsWith(".dat")) {
|
||||||
importer = new MapDatImporter();
|
importer = new MapDatImporter();
|
||||||
@ -57,7 +51,7 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
using (FileStream fs = File.OpenRead(path)) {
|
using (Stream fs = Platform.FileOpen(path)) {
|
||||||
int width, height, length;
|
int width, height, length;
|
||||||
game.World.Reset();
|
game.World.Reset();
|
||||||
game.WorldEvents.RaiseOnNewMap();
|
game.WorldEvents.RaiseOnNewMap();
|
||||||
|
@ -15,14 +15,30 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
InputWidget input;
|
InputWidget input;
|
||||||
const int overwriteIndex = 2;
|
const int overwriteIndex = 2;
|
||||||
static FastColour grey = new FastColour(150, 150, 150);
|
static FastColour grey = new FastColour(150, 150, 150);
|
||||||
|
string textPath;
|
||||||
|
|
||||||
public override void Render(double delta) {
|
public override void Render(double delta) {
|
||||||
base.Render(delta);
|
base.Render(delta);
|
||||||
int cX = game.Width / 2, cY = game.Height / 2;
|
int cX = game.Width / 2, cY = game.Height / 2;
|
||||||
game.Graphics.Draw2DQuad(cX - 250, cY + 90, 500, 2, grey);
|
game.Graphics.Draw2DQuad(cX - 250, cY + 90, 500, 2, grey);
|
||||||
|
|
||||||
if (textPath == null) return;
|
if (textPath == null) return;
|
||||||
SaveMap(textPath);
|
|
||||||
|
bool classic = textPath.EndsWith(".cw");
|
||||||
|
try {
|
||||||
|
using (Stream fs = Platform.FileCreate(textPath)) {
|
||||||
|
IMapFormatExporter exporter = null;
|
||||||
|
if (classic) exporter = new MapCwExporter();
|
||||||
|
else exporter = new MapSchematicExporter();
|
||||||
|
exporter.Save(fs, game);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ErrorHandler.LogError("saving map", ex);
|
||||||
|
MakeDescWidget("&cError while trying to save map");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
game.Chat.Add("&eSaved map to: " + textPath);
|
||||||
|
game.Gui.SetNewScreen(new PauseScreen(game));
|
||||||
textPath = null;
|
textPath = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,23 +95,23 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
void SaveSchematic(Game game, Widget widget) { DoSave(widget, ".schematic"); }
|
void SaveSchematic(Game game, Widget widget) { DoSave(widget, ".schematic"); }
|
||||||
|
|
||||||
void DoSave(Widget widget, string ext) {
|
void DoSave(Widget widget, string ext) {
|
||||||
string text = input.Text.ToString();
|
string file = input.Text.ToString();
|
||||||
if (text.Length == 0) {
|
if (file.Length == 0) {
|
||||||
MakeDescWidget("&ePlease enter a filename"); return;
|
MakeDescWidget("&ePlease enter a filename"); return;
|
||||||
}
|
}
|
||||||
string file = Path.ChangeExtension(text, ext);
|
|
||||||
text = Path.Combine(Program.AppDirectory, "maps");
|
|
||||||
text = Path.Combine(text, file);
|
|
||||||
|
|
||||||
|
file = Path.ChangeExtension(file, ext);
|
||||||
|
string path = Path.Combine("maps", file);
|
||||||
ButtonWidget btn = (ButtonWidget)widget;
|
ButtonWidget btn = (ButtonWidget)widget;
|
||||||
if (File.Exists(text) && btn.OptName == null) {
|
|
||||||
|
if (Platform.FileExists(path) && btn.OptName == null) {
|
||||||
btn.SetText("&cOverwrite existing?");
|
btn.SetText("&cOverwrite existing?");
|
||||||
btn.OptName = "O";
|
btn.OptName = "O";
|
||||||
} else {
|
} else {
|
||||||
// NOTE: We don't immediately save here, because otherwise the 'saving...'
|
// NOTE: We don't immediately save here, because otherwise the 'saving...'
|
||||||
// will not be rendered in time because saving is done on the main thread.
|
// will not be rendered in time because saving is done on the main thread.
|
||||||
MakeDescWidget("Saving..");
|
MakeDescWidget("Saving..");
|
||||||
textPath = text;
|
textPath = path;
|
||||||
RemoveOverwrites();
|
RemoveOverwrites();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,27 +129,6 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
button.SetText(defaultText);
|
button.SetText(defaultText);
|
||||||
}
|
}
|
||||||
|
|
||||||
string textPath;
|
|
||||||
void SaveMap(string path) {
|
|
||||||
bool classic = path.EndsWith(".cw");
|
|
||||||
try {
|
|
||||||
if (File.Exists(path))
|
|
||||||
File.Delete(path);
|
|
||||||
using (FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.Write)) {
|
|
||||||
IMapFormatExporter exporter = null;
|
|
||||||
if (classic) exporter = new MapCwExporter();
|
|
||||||
else exporter = new MapSchematicExporter();
|
|
||||||
exporter.Save(fs, game);
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ErrorHandler.LogError("saving map", ex);
|
|
||||||
MakeDescWidget("&cError while trying to save map");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
game.Chat.Add("&eSaved map to: " + Path.GetFileName(path));
|
|
||||||
game.Gui.SetNewScreen(new PauseScreen(game));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MakeDescWidget(string text) {
|
void MakeDescWidget(string text) {
|
||||||
DisposeDescWidget();
|
DisposeDescWidget();
|
||||||
widgets[widgets.Length - 1] = TextWidget.Create(game, text, textFont)
|
widgets[widgets.Length - 1] = TextWidget.Create(game, text, textFont)
|
||||||
|
@ -10,19 +10,18 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
|
|
||||||
public TexturePackScreen(Game game) : base(game) {
|
public TexturePackScreen(Game game) : base(game) {
|
||||||
titleText = "Select a texture pack zip";
|
titleText = "Select a texture pack zip";
|
||||||
string dir = Path.Combine(Program.AppDirectory, "texpacks");
|
entries = Platform.DirectoryFiles("texpacks", "*.zip");
|
||||||
entries = Directory.GetFiles(dir, "*.zip");
|
|
||||||
|
|
||||||
for (int i = 0; i < entries.Length; i++)
|
for (int i = 0; i < entries.Length; i++) {
|
||||||
entries[i] = Path.GetFileName(entries[i]);
|
entries[i] = Path.GetFileName(entries[i]);
|
||||||
|
}
|
||||||
Array.Sort(entries);
|
Array.Sort(entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void TextButtonClick(Game game, Widget widget) {
|
protected override void TextButtonClick(Game game, Widget widget) {
|
||||||
string file = ((ButtonWidget)widget).Text;
|
string file = ((ButtonWidget)widget).Text;
|
||||||
string dir = Path.Combine(Program.AppDirectory, "texpacks");
|
string path = Path.Combine("texpacks", file);
|
||||||
string path = Path.Combine(dir, file);
|
if (!Platform.FileExists(path)) return;
|
||||||
if (!File.Exists(path)) return;
|
|
||||||
|
|
||||||
int curPage = currentIndex;
|
int curPage = currentIndex;
|
||||||
game.DefaultTexturePack = file;
|
game.DefaultTexturePack = file;
|
||||||
|
@ -17,11 +17,11 @@ namespace ClassicalSharp.Audio {
|
|||||||
|
|
||||||
public void Init(Game game) {
|
public void Init(Game game) {
|
||||||
this.game = game;
|
this.game = game;
|
||||||
string path = Path.Combine(Program.AppDirectory, "audio");
|
if (Platform.DirectoryExists("audio")) {
|
||||||
if (Directory.Exists(path))
|
files = Platform.DirectoryFiles("audio");
|
||||||
files = Directory.GetFiles(path);
|
} else {
|
||||||
else
|
|
||||||
files = new string[0];
|
files = new string[0];
|
||||||
|
}
|
||||||
|
|
||||||
game.MusicVolume = GetVolume(OptionsKey.MusicVolume, OptionsKey.UseMusic);
|
game.MusicVolume = GetVolume(OptionsKey.MusicVolume, OptionsKey.UseMusic);
|
||||||
SetMusic(game.MusicVolume);
|
SetMusic(game.MusicVolume);
|
||||||
@ -60,7 +60,8 @@ namespace ClassicalSharp.Audio {
|
|||||||
musicFiles = new string[musicCount];
|
musicFiles = new string[musicCount];
|
||||||
for (int i = 0, j = 0; i < files.Length; i++) {
|
for (int i = 0, j = 0; i < files.Length; i++) {
|
||||||
if (!Utils.CaselessEnds(files[i], ".ogg")) continue;
|
if (!Utils.CaselessEnds(files[i], ".ogg")) continue;
|
||||||
musicFiles[j] = files[i]; j++;
|
musicFiles[j] = Path.GetFileName(files[i]);
|
||||||
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
disposingMusic = false;
|
disposingMusic = false;
|
||||||
@ -75,10 +76,9 @@ namespace ClassicalSharp.Audio {
|
|||||||
Random rnd = new Random();
|
Random rnd = new Random();
|
||||||
while (!disposingMusic) {
|
while (!disposingMusic) {
|
||||||
string file = musicFiles[rnd.Next(0, musicFiles.Length)];
|
string file = musicFiles[rnd.Next(0, musicFiles.Length)];
|
||||||
string path = Path.Combine(Program.AppDirectory, file);
|
|
||||||
Utils.LogDebug("playing music file: " + file);
|
Utils.LogDebug("playing music file: " + file);
|
||||||
|
|
||||||
using (FileStream fs = File.OpenRead(path)) {
|
using (Stream fs = Platform.FileOpen(file)) {
|
||||||
OggContainer container = new OggContainer(fs);
|
OggContainer container = new OggContainer(fs);
|
||||||
try {
|
try {
|
||||||
musicOut.SetVolume(game.MusicVolume / 100.0f);
|
musicOut.SetVolume(game.MusicVolume / 100.0f);
|
||||||
|
@ -65,7 +65,7 @@ namespace ClassicalSharp.Audio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Sound ReadWave(string file) {
|
Sound ReadWave(string file) {
|
||||||
using (FileStream fs = File.OpenRead(file))
|
using (Stream fs = File.OpenRead(file))
|
||||||
using (BinaryReader r = new BinaryReader(fs))
|
using (BinaryReader r = new BinaryReader(fs))
|
||||||
{
|
{
|
||||||
string fourCC = GetFourCC(r);
|
string fourCC = GetFourCC(r);
|
||||||
|
@ -126,20 +126,19 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OpenChatFile(DateTime now) {
|
void OpenChatFile(DateTime now) {
|
||||||
string basePath = Path.Combine(Program.AppDirectory, "logs");
|
if (!Platform.DirectoryExists("logs")) {
|
||||||
if (!Directory.Exists(basePath))
|
Platform.DirectoryCreate("logs");
|
||||||
Directory.CreateDirectory(basePath);
|
}
|
||||||
|
|
||||||
string date = now.ToString("yyyy-MM-dd");
|
string date = now.ToString("yyyy-MM-dd");
|
||||||
// Ensure multiple instances do not end up overwriting each other's log entries.
|
// Ensure multiple instances do not end up overwriting each other's log entries.
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
string id = i == 0 ? "" : " _" + i;
|
string id = i == 0 ? "" : " _" + i;
|
||||||
string fileName = date + " " + logName + id + ".log";
|
string path = Path.Combine("logs", date + " " + logName + id + ".log");
|
||||||
string path = Path.Combine(basePath, fileName);
|
|
||||||
|
|
||||||
FileStream stream = null;
|
Stream stream = null;
|
||||||
try {
|
try {
|
||||||
stream = File.Open(path, FileMode.Append, FileAccess.Write, FileShare.Read);
|
stream = Platform.FileAppend(path);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
int hresult = Marshal.GetHRForException(ex);
|
int hresult = Marshal.GetHRForException(ex);
|
||||||
uint errorCode = (uint)hresult & 0xFFFF;
|
uint errorCode = (uint)hresult & 0xFFFF;
|
||||||
|
@ -161,9 +161,12 @@ namespace ClassicalSharp {
|
|||||||
defTexturePack = Options.Get(OptionsKey.DefaultTexturePack) ?? "default.zip";
|
defTexturePack = Options.Get(OptionsKey.DefaultTexturePack) ?? "default.zip";
|
||||||
TexturePack extractor = new TexturePack();
|
TexturePack extractor = new TexturePack();
|
||||||
extractor.Extract("default.zip", this);
|
extractor.Extract("default.zip", this);
|
||||||
|
|
||||||
// in case the user's default texture pack doesn't have all required textures
|
// in case the user's default texture pack doesn't have all required textures
|
||||||
if (DefaultTexturePack != "default.zip")
|
string defTexPack = DefaultTexturePack;
|
||||||
extractor.Extract(DefaultTexturePack, this);
|
if (defTexPack != "default.zip") {
|
||||||
|
extractor.Extract(defTexPack, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadOptions() {
|
void LoadOptions() {
|
||||||
|
@ -9,7 +9,6 @@ using ClassicalSharp.Commands;
|
|||||||
using ClassicalSharp.Entities;
|
using ClassicalSharp.Entities;
|
||||||
using ClassicalSharp.Events;
|
using ClassicalSharp.Events;
|
||||||
using ClassicalSharp.GraphicsAPI;
|
using ClassicalSharp.GraphicsAPI;
|
||||||
using ClassicalSharp.Gui;
|
|
||||||
using ClassicalSharp.Map;
|
using ClassicalSharp.Map;
|
||||||
using ClassicalSharp.Mode;
|
using ClassicalSharp.Mode;
|
||||||
using ClassicalSharp.Model;
|
using ClassicalSharp.Model;
|
||||||
@ -231,9 +230,8 @@ namespace ClassicalSharp {
|
|||||||
/// this method returns "default.zip". </remarks>
|
/// this method returns "default.zip". </remarks>
|
||||||
public string DefaultTexturePack {
|
public string DefaultTexturePack {
|
||||||
get {
|
get {
|
||||||
string path = Path.Combine(Program.AppDirectory, "texpacks");
|
string texPath = Path.Combine("texpacks", defTexturePack);
|
||||||
path = Path.Combine(path, defTexturePack);
|
return Platform.FileExists(texPath) && !ClassicMode ? defTexturePack : "default.zip";
|
||||||
return File.Exists(path) && !ClassicMode ? defTexturePack : "default.zip";
|
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
defTexturePack = value;
|
defTexturePack = value;
|
||||||
|
@ -202,13 +202,14 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TakeScreenshot() {
|
void TakeScreenshot() {
|
||||||
string path = PathIO.Combine(Program.AppDirectory, "screenshots");
|
if (!Platform.DirectoryExists("screenshots")) {
|
||||||
if (!Directory.Exists(path))
|
Platform.DirectoryCreate("screenshots");
|
||||||
Directory.CreateDirectory(path);
|
}
|
||||||
|
|
||||||
string timestamp = DateTime.Now.ToString("dd-MM-yyyy-HH-mm-ss");
|
string timestamp = DateTime.Now.ToString("dd-MM-yyyy-HH-mm-ss");
|
||||||
string file = "screenshot_" + timestamp + ".png";
|
string file = "screenshot_" + timestamp + ".png";
|
||||||
path = PathIO.Combine(path, file);
|
string path = PathIO.Combine("screenshots", file);
|
||||||
|
|
||||||
Graphics.TakeScreenshot(path, Width, Height);
|
Graphics.TakeScreenshot(path, Width, Height);
|
||||||
Chat.Add("&eTaken screenshot as: " + file);
|
Chat.Add("&eTaken screenshot as: " + file);
|
||||||
screenshotRequested = false;
|
screenshotRequested = false;
|
||||||
|
@ -21,20 +21,20 @@ namespace ClassicalSharp {
|
|||||||
internal static Game game;
|
internal static Game game;
|
||||||
|
|
||||||
internal static List<string> LoadAll() {
|
internal static List<string> LoadAll() {
|
||||||
string dir = Path.Combine(Program.AppDirectory, "plugins");
|
if (!Platform.DirectoryExists("plugins")) {
|
||||||
if (!Directory.Exists(dir))
|
Platform.DirectoryCreate("plugins");
|
||||||
Directory.CreateDirectory(dir);
|
}
|
||||||
|
|
||||||
Accepted = new EntryList("plugins", "accepted.txt");
|
Accepted = new EntryList("plugins", "accepted.txt");
|
||||||
Denied = new EntryList("plugins", "denied.txt");
|
Denied = new EntryList("plugins", "denied.txt");
|
||||||
Accepted.Load();
|
Accepted.Load();
|
||||||
Denied.Load();
|
Denied.Load();
|
||||||
|
|
||||||
return LoadPlugins(dir);
|
return LoadPlugins();
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<string> LoadPlugins(string dir) {
|
static List<string> LoadPlugins() {
|
||||||
string[] dlls = Directory.GetFiles(dir, "*.dll");
|
string[] dlls = Platform.DirectoryFiles("plugins", "*.dll");
|
||||||
List<string> nonLoaded = null;
|
List<string> nonLoaded = null;
|
||||||
|
|
||||||
for (int i = 0; i < dlls.Length; i++) {
|
for (int i = 0; i < dlls.Length; i++) {
|
||||||
@ -55,8 +55,7 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
public static void Load(string pluginName, bool needsInit) {
|
public static void Load(string pluginName, bool needsInit) {
|
||||||
try {
|
try {
|
||||||
string dir = Path.Combine(Program.AppDirectory, "plugins");
|
string path = Path.Combine("plguins", pluginName + ".dll");
|
||||||
string path = Path.Combine(dir, pluginName + ".dll");
|
|
||||||
Assembly lib = Assembly.LoadFrom(path);
|
Assembly lib = Assembly.LoadFrom(path);
|
||||||
Type[] types = lib.GetTypes();
|
Type[] types = lib.GetTypes();
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
@ -553,9 +554,10 @@ namespace ClassicalSharp.GraphicsAPI {
|
|||||||
device.GetRenderTargetData(backbuffer, tempSurface);
|
device.GetRenderTargetData(backbuffer, tempSurface);
|
||||||
LockedRectangle rect = tempSurface.LockRectangle(LockFlags.ReadOnly | LockFlags.NoDirtyUpdate);
|
LockedRectangle rect = tempSurface.LockRectangle(LockFlags.ReadOnly | LockFlags.NoDirtyUpdate);
|
||||||
|
|
||||||
using (Bitmap bmp = new Bitmap(width, height, width * sizeof(int),
|
using (Bitmap bmp = new Bitmap(width, height, width * sizeof(int), PixelFormat.Format32bppRgb, rect.DataPointer)) {
|
||||||
PixelFormat.Format32bppRgb, rect.DataPointer)) {
|
using (Stream fs = Platform.FileCreate(output)) {
|
||||||
bmp.Save(output, ImageFormat.Png);
|
Platform.WriteBmp(bmp, fs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tempSurface.UnlockRectangle();
|
tempSurface.UnlockRectangle();
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
@ -551,7 +552,10 @@ namespace ClassicalSharp.GraphicsAPI {
|
|||||||
using (FastBitmap fastBmp = new FastBitmap(bmp, true, false))
|
using (FastBitmap fastBmp = new FastBitmap(bmp, true, false))
|
||||||
GL.ReadPixels(0, 0, width, height, GlPixelFormat.Bgra, PixelType.UnsignedByte, fastBmp.Scan0);
|
GL.ReadPixels(0, 0, width, height, GlPixelFormat.Bgra, PixelType.UnsignedByte, fastBmp.Scan0);
|
||||||
bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
||||||
bmp.Save(output, ImageFormat.Png);
|
|
||||||
|
using (Stream fs = Platform.FileCreate(output)) {
|
||||||
|
Platform.WriteBmp(bmp, fs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,8 +342,9 @@ namespace ClassicalSharp.GraphicsAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
using (FileStream fs = File.Create(output))
|
using (Stream fs = Platform.FileCreate(output)) {
|
||||||
Platform.WriteBmp(bmp, fs);
|
Platform.WriteBmp(bmp, fs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,12 +74,12 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
internal void DownloadTexturePack(string url) {
|
internal void DownloadTexturePack(string url) {
|
||||||
if (game.DeniedUrls.Has(url)) return;
|
if (game.DeniedUrls.Has(url)) return;
|
||||||
string path = TextureCache.MakePath(url), etag = null;
|
string etag = null;
|
||||||
DateTime lastModified = DateTime.MinValue;
|
DateTime lastModified = DateTime.MinValue;
|
||||||
|
|
||||||
if (File.Exists(path)) {
|
if (TextureCache.HasUrl(url)) {
|
||||||
lastModified = TextureCache.GetLastModified(url, path, game.LastModified);
|
lastModified = TextureCache.GetLastModified(url, game.LastModified);
|
||||||
etag = TextureCache.GetETag(url, path, game.ETags);
|
etag = TextureCache.GetETag(url, game.ETags);
|
||||||
}
|
}
|
||||||
|
|
||||||
TexturePack.ExtractCurrent(game, url);
|
TexturePack.ExtractCurrent(game, url);
|
||||||
|
@ -41,13 +41,14 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void LoadIcon() {
|
public void LoadIcon() {
|
||||||
string launcherPath = Path.Combine(Program.AppDirectory, "Launcher2.exe");
|
string launcherFile = "Launcher2.exe";
|
||||||
if (!File.Exists(launcherPath)) {
|
if (!Platform.FileExists(launcherFile)) {
|
||||||
launcherPath = Path.Combine(Program.AppDirectory, "Launcher.exe");
|
launcherFile = "Launcher.exe";
|
||||||
}
|
}
|
||||||
if (!File.Exists(launcherPath)) return;
|
if (!Platform.FileExists(launcherFile)) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
string launcherPath = Path.Combine(Platform.AppDirectory, launcherFile);
|
||||||
Icon = Icon.ExtractAssociatedIcon(launcherPath);
|
Icon = Icon.ExtractAssociatedIcon(launcherPath);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ErrorHandler.LogError("DesktopWindow.LoadIcon()", ex);
|
ErrorHandler.LogError("DesktopWindow.LoadIcon()", ex);
|
||||||
|
@ -13,6 +13,8 @@ namespace ClassicalSharp {
|
|||||||
/// <summary> Abstracts away platform specific operations. </summary>
|
/// <summary> Abstracts away platform specific operations. </summary>
|
||||||
public static class Platform {
|
public static class Platform {
|
||||||
|
|
||||||
|
public static string AppDirectory;
|
||||||
|
|
||||||
public static bool ValidBitmap(Bitmap bmp) {
|
public static bool ValidBitmap(Bitmap bmp) {
|
||||||
// Mono seems to be returning a bitmap with a native pointer of zero in some weird cases.
|
// Mono seems to be returning a bitmap with a native pointer of zero in some weird cases.
|
||||||
// We can detect this as property access raises an ArgumentException.
|
// We can detect this as property access raises an ArgumentException.
|
||||||
@ -70,5 +72,65 @@ namespace ClassicalSharp {
|
|||||||
return config != null && config == Bitmap.Config.Argb8888;
|
return config != null && config == Bitmap.Config.Argb8888;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static FileStream FileOpen(string relPath) {
|
||||||
|
string path = Path.Combine(AppDirectory, relPath);
|
||||||
|
return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FileStream FileCreate(string relPath) {
|
||||||
|
string path = Path.Combine(AppDirectory, relPath);
|
||||||
|
return new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FileStream FileAppend(string relPath) {
|
||||||
|
string path = Path.Combine(AppDirectory, relPath);
|
||||||
|
return new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool FileExists(string relPath) {
|
||||||
|
string path = Path.Combine(AppDirectory, relPath);
|
||||||
|
return File.Exists(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime FileGetWriteTime(string relPath) {
|
||||||
|
string path = Path.Combine(AppDirectory, relPath);
|
||||||
|
return File.GetLastWriteTimeUtc(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FileSetWriteTime(string relPath, DateTime time) {
|
||||||
|
string path = Path.Combine(AppDirectory, relPath);
|
||||||
|
File.SetLastWriteTimeUtc(path, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool DirectoryExists(string relPath) {
|
||||||
|
string path = Path.Combine(AppDirectory, relPath);
|
||||||
|
return Directory.Exists(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DirectoryCreate(string relPath) {
|
||||||
|
string path = Path.Combine(AppDirectory, relPath);
|
||||||
|
Directory.CreateDirectory(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string[] DirectoryFiles(string relPath) {
|
||||||
|
string path = Path.Combine(AppDirectory, relPath);
|
||||||
|
return Directory.GetFiles(relPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string[] DirectoryFiles(string relPath, string filter) {
|
||||||
|
string path = Path.Combine(AppDirectory, relPath);
|
||||||
|
return Directory.GetFiles(relPath, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void WriteAllText(string relPath, string text) {
|
||||||
|
string path = Path.Combine(AppDirectory, relPath);
|
||||||
|
File.WriteAllText(path, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void WriteAllBytes(string relPath, byte[] data) {
|
||||||
|
string path = Path.Combine(AppDirectory, relPath);
|
||||||
|
File.WriteAllBytes(path, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using ClassicalSharp.Textures;
|
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
@ -12,21 +11,21 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
public const string AppName = "ClassicalSharp 0.99.9.94";
|
public const string AppName = "ClassicalSharp 0.99.9.94";
|
||||||
|
|
||||||
public static string AppDirectory;
|
|
||||||
#if !LAUNCHER
|
#if !LAUNCHER
|
||||||
[STAThread]
|
[STAThread]
|
||||||
static void Main(string[] args) {
|
static void Main(string[] args) {
|
||||||
AppDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
Platform.AppDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
CleanupMainDirectory();
|
CleanupMainDirectory();
|
||||||
|
|
||||||
string path = Path.Combine(Program.AppDirectory, "texpacks");
|
string defPath = Path.Combine("texpacks", "default.zip");
|
||||||
if (!File.Exists(Path.Combine(path, "default.zip"))) {
|
if (!Platform.FileExists(defPath)) {
|
||||||
Message("default.zip not found, try running the launcher first."); return;
|
ErrorHandler.ShowDialog("Missing file", "default.zip not found, try running the launcher first.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
path = Path.Combine(AppDirectory, "OpenTK.dll");
|
if (!Platform.FileExists("OpenTK.dll")) {
|
||||||
if (!File.Exists(path)) {
|
ErrorHandler.ShowDialog("Missing file", "OpenTK.dll needs to be in the same folder as the game");
|
||||||
Message("OpenTK.dll needs to be in the same folder as the game"); return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: we purposely put this in another method, as we need to ensure
|
// NOTE: we purposely put this in another method, as we need to ensure
|
||||||
@ -36,8 +35,7 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void RunGame(string[] args) {
|
static void RunGame(string[] args) {
|
||||||
string logPath = Path.Combine(AppDirectory, "client.log");
|
ErrorHandler.InstallHandler("client.log");
|
||||||
ErrorHandler.InstallHandler(logPath);
|
|
||||||
OpenTK.Configuration.SkipPerfCountersHack();
|
OpenTK.Configuration.SkipPerfCountersHack();
|
||||||
Utils.LogDebug("Starting " + AppName + "..");
|
Utils.LogDebug("Starting " + AppName + "..");
|
||||||
|
|
||||||
@ -70,9 +68,6 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// put in separate function, because we don't want to load winforms assembly if possible
|
|
||||||
static void Message(string message) { MessageBox.Show(message, "Missing file"); }
|
|
||||||
|
|
||||||
static void RunMultiplayer(string[] args, bool nullContext, int width, int height) {
|
static void RunMultiplayer(string[] args, bool nullContext, int width, int height) {
|
||||||
IPAddress ip = null;
|
IPAddress ip = null;
|
||||||
if (!IPAddress.TryParse(args[2], out ip)) {
|
if (!IPAddress.TryParse(args[2], out ip)) {
|
||||||
@ -97,14 +92,14 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
internal static void CleanupMainDirectory() {
|
public static void CleanupMainDirectory() {
|
||||||
string mapPath = Path.Combine(Program.AppDirectory, "maps");
|
if (!Platform.DirectoryExists("maps")) {
|
||||||
if (!Directory.Exists(mapPath))
|
Platform.DirectoryCreate("maps");
|
||||||
Directory.CreateDirectory(mapPath);
|
}
|
||||||
|
|
||||||
string texPath = Path.Combine(Program.AppDirectory, "texpacks");
|
if (!Platform.DirectoryExists("texpacks")) {
|
||||||
if (!Directory.Exists(texPath))
|
Platform.DirectoryCreate("texpacks");
|
||||||
Directory.CreateDirectory(texPath);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -43,7 +43,7 @@ namespace ClassicalSharp.Textures {
|
|||||||
animsBuffer = new FastBitmap(animBmp, true, true);
|
animsBuffer = new FastBitmap(animBmp, true, true);
|
||||||
} else if (e.Name == "animations.txt" || e.Name == "animation.txt") {
|
} else if (e.Name == "animations.txt" || e.Name == "animation.txt") {
|
||||||
MemoryStream stream = new MemoryStream(e.Data);
|
MemoryStream stream = new MemoryStream(e.Data);
|
||||||
StreamReader reader = new StreamReader(stream);
|
StreamReader reader = new StreamReader(stream, false);
|
||||||
ReadAnimationsDescription(reader);
|
ReadAnimationsDescription(reader);
|
||||||
} else if (e.Name == "uselavaanim") {
|
} else if (e.Name == "uselavaanim") {
|
||||||
useLavaAnim = true;
|
useLavaAnim = true;
|
||||||
|
@ -25,12 +25,11 @@ namespace ClassicalSharp.Textures {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool Load() {
|
public bool Load() {
|
||||||
string path = Path.Combine(Program.AppDirectory, folder);
|
string path = Path.Combine(folder, file);
|
||||||
path = Path.Combine(path, file);
|
if (!Platform.FileExists(path)) return true;
|
||||||
if (!File.Exists(path)) return true;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
using (Stream fs = File.OpenRead(path))
|
using (Stream fs = Platform.FileOpen(path))
|
||||||
using (StreamReader reader = new StreamReader(fs, false))
|
using (StreamReader reader = new StreamReader(fs, false))
|
||||||
{
|
{
|
||||||
string line;
|
string line;
|
||||||
@ -49,11 +48,12 @@ namespace ClassicalSharp.Textures {
|
|||||||
|
|
||||||
public bool Save() {
|
public bool Save() {
|
||||||
try {
|
try {
|
||||||
string path = Path.Combine(Program.AppDirectory, folder);
|
if (!Platform.DirectoryExists(folder)) {
|
||||||
if (!Directory.Exists(path))
|
Platform.DirectoryCreate(folder);
|
||||||
Directory.CreateDirectory(path);
|
}
|
||||||
|
|
||||||
using (Stream fs = File.Create(Path.Combine(path, file)))
|
string path = Path.Combine(folder, file);
|
||||||
|
using (Stream fs = Platform.FileCreate(path))
|
||||||
using (StreamWriter writer = new StreamWriter(fs))
|
using (StreamWriter writer = new StreamWriter(fs))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Entries.Count; i++)
|
for (int i = 0; i < Entries.Count; i++)
|
||||||
|
@ -14,18 +14,16 @@ namespace ClassicalSharp.Textures {
|
|||||||
public static class TextureCache {
|
public static class TextureCache {
|
||||||
|
|
||||||
/// <summary> Gets whether the given url has data associated with it in the cache. </summary>
|
/// <summary> Gets whether the given url has data associated with it in the cache. </summary>
|
||||||
public static bool HasUrl(string url) {
|
public static bool HasUrl(string url) { return Platform.FileExists(MakePath(url)); }
|
||||||
return File.Exists(MakePath(url));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> Gets the stream of data associated with the url from the cache, returning null if the
|
/// <summary> Gets the stream of data associated with the url from the cache, returning null if the
|
||||||
/// data for the url was not found in the cache. </summary>
|
/// data for the url was not found in the cache. </summary>
|
||||||
public static FileStream GetStream(string url) {
|
public static FileStream GetStream(string url) {
|
||||||
string path = MakePath(url);
|
string path = MakePath(url);
|
||||||
if (!File.Exists(path)) return null;
|
if (!Platform.FileExists(path)) return null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return File.OpenRead(path);
|
return Platform.FileOpen(path);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
ErrorHandler.LogError("Cache.GetData", ex);
|
ErrorHandler.LogError("Cache.GetData", ex);
|
||||||
return null;
|
return null;
|
||||||
@ -34,17 +32,18 @@ namespace ClassicalSharp.Textures {
|
|||||||
|
|
||||||
/// <summary> Gets the time the data associated with the url from the cache was last modified,
|
/// <summary> Gets the time the data associated with the url from the cache was last modified,
|
||||||
/// returning DateTime.MinValue if data for the url was not found in the cache. </summary>
|
/// returning DateTime.MinValue if data for the url was not found in the cache. </summary>
|
||||||
public static DateTime GetLastModified(string url, string path, EntryList tags) {
|
public static DateTime GetLastModified(string url, EntryList tags) {
|
||||||
string entry = GetFromTags(url, tags);
|
string entry = GetFromTags(url, tags);
|
||||||
long ticks = 0;
|
long ticks = 0;
|
||||||
if (entry != null && long.TryParse(entry, out ticks)) {
|
if (entry != null && long.TryParse(entry, out ticks)) {
|
||||||
return new DateTime(ticks, DateTimeKind.Utc);
|
return new DateTime(ticks, DateTimeKind.Utc);
|
||||||
} else {
|
} else {
|
||||||
return File.GetLastWriteTimeUtc(path);
|
string path = MakePath(url);
|
||||||
|
return Platform.FileGetWriteTime(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetETag(string url, string path, EntryList tags) {
|
public static string GetETag(string url, EntryList tags) {
|
||||||
return GetFromTags(url, tags);
|
return GetFromTags(url, tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,12 +66,13 @@ namespace ClassicalSharp.Textures {
|
|||||||
public static void Add(string url, Bitmap bmp) {
|
public static void Add(string url, Bitmap bmp) {
|
||||||
string path = MakePath(url);
|
string path = MakePath(url);
|
||||||
try {
|
try {
|
||||||
string basePath = PathIO.Combine(Program.AppDirectory, Folder);
|
if (!Platform.DirectoryExists(Folder)) {
|
||||||
if (!Directory.Exists(basePath))
|
Platform.DirectoryCreate(Folder);
|
||||||
Directory.CreateDirectory(basePath);
|
}
|
||||||
|
|
||||||
using (FileStream fs = File.Create(path))
|
using (Stream fs = Platform.FileCreate(path)) {
|
||||||
Platform.WriteBmp(bmp, fs);
|
Platform.WriteBmp(bmp, fs);
|
||||||
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
ErrorHandler.LogError("Cache.AddToCache", ex);
|
ErrorHandler.LogError("Cache.AddToCache", ex);
|
||||||
}
|
}
|
||||||
@ -82,10 +82,11 @@ namespace ClassicalSharp.Textures {
|
|||||||
public static void Add(string url, byte[] data) {
|
public static void Add(string url, byte[] data) {
|
||||||
string path = MakePath(url);
|
string path = MakePath(url);
|
||||||
try {
|
try {
|
||||||
string basePath = PathIO.Combine(Program.AppDirectory, Folder);
|
if (!Platform.DirectoryExists(Folder)) {
|
||||||
if (!Directory.Exists(basePath))
|
Platform.DirectoryCreate(Folder);
|
||||||
Directory.CreateDirectory(basePath);
|
}
|
||||||
File.WriteAllBytes(path, data);
|
|
||||||
|
Platform.WriteAllBytes(path, data);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
ErrorHandler.LogError("Cache.AddToCache", ex);
|
ErrorHandler.LogError("Cache.AddToCache", ex);
|
||||||
}
|
}
|
||||||
@ -114,12 +115,7 @@ namespace ClassicalSharp.Textures {
|
|||||||
|
|
||||||
|
|
||||||
const string Folder = "texturecache";
|
const string Folder = "texturecache";
|
||||||
|
public static string MakePath(string url) { return PathIO.Combine(Folder, CRC32(url)); }
|
||||||
public static string MakePath(string url) {
|
|
||||||
string crc32 = CRC32(url);
|
|
||||||
string basePath = PathIO.Combine(Program.AppDirectory, Folder);
|
|
||||||
return PathIO.Combine(basePath, crc32);
|
|
||||||
}
|
|
||||||
|
|
||||||
static string CRC32(string url) {
|
static string CRC32(string url) {
|
||||||
byte[] data = Encoding.UTF8.GetBytes(url);
|
byte[] data = Encoding.UTF8.GetBytes(url);
|
||||||
|
@ -17,11 +17,11 @@ namespace ClassicalSharp.Textures {
|
|||||||
|
|
||||||
Game game;
|
Game game;
|
||||||
|
|
||||||
public void Extract(string path, Game game) {
|
public void Extract(string file, Game game) {
|
||||||
path = PathIO.Combine("texpacks", path);
|
string path = PathIO.Combine("texpacks", file);
|
||||||
path = PathIO.Combine(Program.AppDirectory, path);
|
using (Stream fs = Platform.FileOpen(path)) {
|
||||||
using (Stream fs = File.OpenRead(path))
|
|
||||||
Extract(fs, game);
|
Extract(fs, game);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Extract(Stream stream, Game game) {
|
public void Extract(Stream stream, Game game) {
|
||||||
|
@ -11,14 +11,12 @@ namespace ClassicalSharp {
|
|||||||
/// and also logs it to a specified log file. </summary>
|
/// and also logs it to a specified log file. </summary>
|
||||||
public static class ErrorHandler {
|
public static class ErrorHandler {
|
||||||
|
|
||||||
static string logFile = "crash.log";
|
|
||||||
static string fileName = "crash.log";
|
static string fileName = "crash.log";
|
||||||
|
|
||||||
/// <summary> Adds a handler for when a unhandled exception occurs, unless
|
/// <summary> Adds a handler for when a unhandled exception occurs, unless
|
||||||
/// a debugger is attached to the process in which case this does nothing. </summary>
|
/// a debugger is attached to the process in which case this does nothing. </summary>
|
||||||
public static void InstallHandler(string logFile) {
|
public static void InstallHandler(string logFile) {
|
||||||
ErrorHandler.logFile = logFile;
|
fileName = logFile;
|
||||||
fileName = Path.GetFileName(logFile);
|
|
||||||
if (!Debugger.IsAttached)
|
if (!Debugger.IsAttached)
|
||||||
AppDomain.CurrentDomain.UnhandledException += UnhandledException;
|
AppDomain.CurrentDomain.UnhandledException += UnhandledException;
|
||||||
}
|
}
|
||||||
@ -40,7 +38,9 @@ namespace ClassicalSharp {
|
|||||||
Exception ex = (Exception)e.ExceptionObject;
|
Exception ex = (Exception)e.ExceptionObject;
|
||||||
bool wroteToCrashLog = true;
|
bool wroteToCrashLog = true;
|
||||||
try {
|
try {
|
||||||
using (StreamWriter w = new StreamWriter(logFile, true)) {
|
using (Stream fs = Platform.FileAppend(fileName))
|
||||||
|
using (StreamWriter w = new StreamWriter(fs))
|
||||||
|
{
|
||||||
w.WriteLine("=== crash occurred ===");
|
w.WriteLine("=== crash occurred ===");
|
||||||
w.WriteLine("Time: " + DateTime.Now);
|
w.WriteLine("Time: " + DateTime.Now);
|
||||||
|
|
||||||
@ -72,12 +72,12 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
string line1 = "ClassicalSharp crashed.";
|
string line1 = "ClassicalSharp crashed.";
|
||||||
if (wroteToCrashLog) {
|
if (wroteToCrashLog) {
|
||||||
line1 += " The cause has also been logged to \"" + fileName + "\" in " + Program.AppDirectory;
|
line1 += " The cause has also been logged to \"" + fileName + "\" in " + Platform.AppDirectory;
|
||||||
}
|
}
|
||||||
string line2 = "Please report the crash to github.com/UnknownShadow200/ClassicalSharp/issues so we can fix it.";
|
string line2 = "Please report the crash to github.com/UnknownShadow200/ClassicalSharp/issues so we can fix it.";
|
||||||
line2 += Environment.NewLine + Environment.NewLine + Format(ex);
|
line2 += Environment.NewLine + Environment.NewLine + Format(ex);
|
||||||
|
|
||||||
MessageBox.Show(line1 + Environment.NewLine + Environment.NewLine + line2, "We're sorry");
|
ShowDialog("We're sorry", line1 + Environment.NewLine + Environment.NewLine + line2);
|
||||||
Environment.Exit(1);
|
Environment.Exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,16 +93,23 @@ namespace ClassicalSharp {
|
|||||||
/// <summary> Logs an error that occured at the specified location to the log file. </summary>
|
/// <summary> Logs an error that occured at the specified location to the log file. </summary>
|
||||||
public static bool LogError(string location, string text) {
|
public static bool LogError(string location, string text) {
|
||||||
try {
|
try {
|
||||||
using (StreamWriter writer = new StreamWriter(logFile, true)) {
|
using (Stream fs = Platform.FileAppend(fileName))
|
||||||
writer.WriteLine("=== handled error ===");
|
using (StreamWriter w = new StreamWriter(fs))
|
||||||
writer.WriteLine("Occured when: " + location);
|
{
|
||||||
writer.WriteLine(text);
|
w.WriteLine("=== handled error ===");
|
||||||
writer.WriteLine();
|
w.WriteLine("Occured when: " + location);
|
||||||
|
w.WriteLine(text);
|
||||||
|
w.WriteLine();
|
||||||
}
|
}
|
||||||
} catch (Exception) {
|
} catch (Exception) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// put in separate function, because we don't want to load winforms assembly if possible
|
||||||
|
public static void ShowDialog(string title, string msg) {
|
||||||
|
MessageBox.Show(msg, title);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -190,14 +190,8 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
|
|
||||||
public static bool Load() {
|
public static bool Load() {
|
||||||
// Both of these are from when running from the launcher
|
|
||||||
if (Program.AppDirectory == null)
|
|
||||||
Program.AppDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
|
||||||
Program.CleanupMainDirectory();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
string path = Path.Combine(Program.AppDirectory, Filename);
|
using (Stream fs = Platform.FileOpen(Filename))
|
||||||
using (Stream fs = File.OpenRead(path))
|
|
||||||
using (StreamReader reader = new StreamReader(fs, false))
|
using (StreamReader reader = new StreamReader(fs, false))
|
||||||
{
|
{
|
||||||
LoadFrom(reader);
|
LoadFrom(reader);
|
||||||
@ -239,8 +233,7 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
public static bool Save() {
|
public static bool Save() {
|
||||||
try {
|
try {
|
||||||
string path = Path.Combine(Program.AppDirectory, Filename);
|
using (Stream fs = Platform.FileCreate(Filename))
|
||||||
using (Stream fs = File.Create(path))
|
|
||||||
using (StreamWriter writer = new StreamWriter(fs))
|
using (StreamWriter writer = new StreamWriter(fs))
|
||||||
{
|
{
|
||||||
SaveTo(writer);
|
SaveTo(writer);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using ClassicalSharp;
|
||||||
using ClassicalSharp.Network;
|
using ClassicalSharp.Network;
|
||||||
using Launcher.Gui.Views;
|
using Launcher.Gui.Views;
|
||||||
using Launcher.Patcher;
|
using Launcher.Patcher;
|
||||||
@ -90,7 +90,7 @@ namespace Launcher.Gui.Screens {
|
|||||||
|
|
||||||
void GotoNextMenu(int x, int y) {
|
void GotoNextMenu(int x, int y) {
|
||||||
game.Downloader.Clear();
|
game.Downloader.Clear();
|
||||||
if (File.Exists("options.txt")) {
|
if (Platform.FileExists("options.txt")) {
|
||||||
game.SetScreen(new MainScreen(game));
|
game.SetScreen(new MainScreen(game));
|
||||||
} else {
|
} else {
|
||||||
game.SetScreen(new ChooseModeScreen(game, true));
|
game.SetScreen(new ChooseModeScreen(game, true));
|
||||||
|
@ -39,11 +39,11 @@ namespace Launcher.Gui.Views {
|
|||||||
const string dateFormat = "dd-MM-yyyy HH:mm";
|
const string dateFormat = "dd-MM-yyyy HH:mm";
|
||||||
protected override void MakeWidgets() {
|
protected override void MakeWidgets() {
|
||||||
widgetIndex = 0;
|
widgetIndex = 0;
|
||||||
string exePath = Path.Combine(Program.AppDirectory, "ClassicalSharp.exe");
|
DateTime writeTime = Platform.FileGetWriteTime("ClassicalSharp.exe");
|
||||||
|
|
||||||
Makers.Label(this, "Your build:", textFont)
|
Makers.Label(this, "Your build:", textFont)
|
||||||
.SetLocation(Anchor.Centre, Anchor.Centre, -55, -120);
|
.SetLocation(Anchor.Centre, Anchor.Centre, -55, -120);
|
||||||
string yourBuild = File.GetLastWriteTime(exePath).ToString(dateFormat);
|
string yourBuild = writeTime.ToLocalTime().ToString(dateFormat);
|
||||||
Makers.Label(this, yourBuild, textFont)
|
Makers.Label(this, yourBuild, textFont)
|
||||||
.SetLocation(Anchor.Centre, Anchor.Centre, 70, -120);
|
.SetLocation(Anchor.Centre, Anchor.Centre, 70, -120);
|
||||||
|
|
||||||
|
@ -17,28 +17,31 @@ namespace Launcher {
|
|||||||
fontPng = false; terrainPng = false;
|
fontPng = false; terrainPng = false;
|
||||||
Options.Load();
|
Options.Load();
|
||||||
LauncherSkin.LoadFromOptions();
|
LauncherSkin.LoadFromOptions();
|
||||||
if (Options.Get("nostalgia-classicbg") != null)
|
|
||||||
|
if (Options.Get("nostalgia-classicbg") != null) {
|
||||||
ClassicBackground = Options.GetBool("nostalgia-classicbg", false);
|
ClassicBackground = Options.GetBool("nostalgia-classicbg", false);
|
||||||
else
|
} else {
|
||||||
ClassicBackground = Options.GetBool("mode-classic", false);
|
ClassicBackground = Options.GetBool("mode-classic", false);
|
||||||
|
}
|
||||||
|
|
||||||
string texDir = Path.Combine(Program.AppDirectory, "texpacks");
|
|
||||||
string texPack = Options.Get(OptionsKey.DefaultTexturePack) ?? "default.zip";
|
string texPack = Options.Get(OptionsKey.DefaultTexturePack) ?? "default.zip";
|
||||||
texPack = Path.Combine(texDir, texPack);
|
string texPath = Path.Combine("texpacks", texPack);
|
||||||
|
|
||||||
if (!File.Exists(texPack))
|
if (!Platform.FileExists(texPath)) {
|
||||||
texPack = Path.Combine(texDir, "default.zip");
|
texPath = Path.Combine("texpacks", "default.zip");
|
||||||
if (!File.Exists(texPack)) return;
|
}
|
||||||
|
if (!Platform.FileExists(texPath)) return;
|
||||||
|
|
||||||
ExtractTexturePack(texPack);
|
ExtractTexturePack(texPath);
|
||||||
|
// user selected texture pack is missing some required .png files
|
||||||
if (!fontPng || !terrainPng) {
|
if (!fontPng || !terrainPng) {
|
||||||
texPack = Path.Combine(texDir, "default.zip");
|
texPath = Path.Combine("texpacks", "default.zip");
|
||||||
ExtractTexturePack(texPack);
|
ExtractTexturePack(texPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractTexturePack(string texPack) {
|
void ExtractTexturePack(string relPath) {
|
||||||
using (Stream fs = new FileStream(texPack, FileMode.Open, FileAccess.Read, FileShare.Read)) {
|
using (Stream fs = Platform.FileOpen(relPath)) {
|
||||||
ZipReader reader = new ZipReader();
|
ZipReader reader = new ZipReader();
|
||||||
reader.SelectZipEntry = SelectZipEntry;
|
reader.SelectZipEntry = SelectZipEntry;
|
||||||
reader.ProcessZipEntry = ProcessZipEntry;
|
reader.ProcessZipEntry = ProcessZipEntry;
|
||||||
|
@ -74,6 +74,8 @@ namespace Launcher {
|
|||||||
Window.FocusedChanged += FocusedChanged;
|
Window.FocusedChanged += FocusedChanged;
|
||||||
Window.WindowStateChanged += Resize;
|
Window.WindowStateChanged += Resize;
|
||||||
Window.Keyboard.KeyDown += KeyDown;
|
Window.Keyboard.KeyDown += KeyDown;
|
||||||
|
|
||||||
|
ClassicalSharp.Program.CleanupMainDirectory();
|
||||||
LoadFont();
|
LoadFont();
|
||||||
logoFont = new Font(FontName, 32, FontStyle.Regular);
|
logoFont = new Font(FontName, 32, FontStyle.Regular);
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using ClassicalSharp;
|
||||||
using ClassicalSharp.Textures;
|
using ClassicalSharp.Textures;
|
||||||
|
|
||||||
namespace Launcher.Patcher {
|
namespace Launcher.Patcher {
|
||||||
@ -8,21 +9,21 @@ namespace Launcher.Patcher {
|
|||||||
public sealed class ResourceChecker {
|
public sealed class ResourceChecker {
|
||||||
|
|
||||||
public void CheckResourceExistence() {
|
public void CheckResourceExistence() {
|
||||||
string audioPath = Path.Combine(Program.AppDirectory, "audio");
|
if (!Platform.DirectoryExists("audio")) {
|
||||||
if (!Directory.Exists(audioPath))
|
Platform.DirectoryCreate("audio");
|
||||||
Directory.CreateDirectory(audioPath);
|
}
|
||||||
|
|
||||||
DigSoundsExist = CheckDigSoundsExist();
|
DigSoundsExist = CheckDigSoundsExist();
|
||||||
StepSoundsExist = CheckStepSoundsExist();
|
StepSoundsExist = CheckStepSoundsExist();
|
||||||
AllResourcesExist = DigSoundsExist && StepSoundsExist;
|
AllResourcesExist = DigSoundsExist && StepSoundsExist;
|
||||||
|
|
||||||
string texDir = Path.Combine(Program.AppDirectory, "texpacks");
|
string defPath = Path.Combine("texpacks", "default.zip");
|
||||||
string zipPath = Path.Combine(texDir, "default.zip");
|
if (Platform.FileExists(defPath)) {
|
||||||
bool defaultZipExists = File.Exists(zipPath);
|
CheckDefaultZip(defPath);
|
||||||
if (File.Exists(zipPath))
|
}
|
||||||
CheckDefaultZip(zipPath);
|
|
||||||
|
|
||||||
CheckTexturePack();
|
CheckTexturePack();
|
||||||
CheckMusic(audioPath);
|
CheckMusic();
|
||||||
CheckSounds();
|
CheckSounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,11 +45,11 @@ namespace Launcher.Patcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckMusic(string audioPath) {
|
void CheckMusic() {
|
||||||
string[] files = ResourceList.MusicFiles;
|
string[] files = ResourceList.MusicFiles;
|
||||||
for (int i = 0; i < files.Length; i++) {
|
for (int i = 0; i < files.Length; i++) {
|
||||||
string file = Path.Combine(audioPath, files[i]);
|
string path = Path.Combine("audio", files[i]);
|
||||||
musicExists[i] = File.Exists(file);
|
musicExists[i] = Platform.FileExists(path);
|
||||||
if (musicExists[i]) continue;
|
if (musicExists[i]) continue;
|
||||||
|
|
||||||
DownloadSize += musicSizes[i] / 1024f;
|
DownloadSize += musicSizes[i] / 1024f;
|
||||||
@ -73,13 +74,14 @@ namespace Launcher.Patcher {
|
|||||||
public int ResourcesCount;
|
public int ResourcesCount;
|
||||||
internal bool[] musicExists = new bool[7];
|
internal bool[] musicExists = new bool[7];
|
||||||
|
|
||||||
void CheckDefaultZip(string path) {
|
void CheckDefaultZip(string relPath) {
|
||||||
ZipReader reader = new ZipReader();
|
ZipReader reader = new ZipReader();
|
||||||
reader.SelectZipEntry = SelectZipEntry;
|
reader.SelectZipEntry = SelectZipEntry;
|
||||||
reader.ProcessZipEntry = ProcessZipEntry;
|
reader.ProcessZipEntry = ProcessZipEntry;
|
||||||
|
|
||||||
using (Stream src = new FileStream(path, FileMode.Open, FileAccess.Read))
|
using (Stream src = Platform.FileOpen(relPath)) {
|
||||||
reader.Extract(src);
|
reader.Extract(src);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SelectZipEntry(string filename) {
|
bool SelectZipEntry(string filename) {
|
||||||
@ -98,20 +100,18 @@ namespace Launcher.Patcher {
|
|||||||
|
|
||||||
bool CheckDigSoundsExist() {
|
bool CheckDigSoundsExist() {
|
||||||
string[] files = ResourceList.DigSounds;
|
string[] files = ResourceList.DigSounds;
|
||||||
string path = Path.Combine(Program.AppDirectory, "audio");
|
|
||||||
for (int i = 0; i < files.Length; i++) {
|
for (int i = 0; i < files.Length; i++) {
|
||||||
string file = "dig_" + files[i] + ".wav";
|
string path = Path.Combine("audio", "dig_" + files[i] + ".wav");
|
||||||
if (!File.Exists(Path.Combine(path, file))) return false;
|
if (!Platform.FileExists(path)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckStepSoundsExist() {
|
bool CheckStepSoundsExist() {
|
||||||
string[] files = ResourceList.StepSounds;
|
string[] files = ResourceList.StepSounds;
|
||||||
string path = Path.Combine(Program.AppDirectory, "audio");
|
|
||||||
for (int i = 0; i < files.Length; i++) {
|
for (int i = 0; i < files.Length; i++) {
|
||||||
string file = "step_" + files[i] + ".wav";
|
string path = Path.Combine("audio", "step_" + files[i] + ".wav");
|
||||||
if (!File.Exists(Path.Combine(path, file))) return false;
|
if (!Platform.FileExists(path)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -128,9 +128,8 @@ namespace Launcher.Patcher {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (data == null) continue;
|
if (data == null) continue;
|
||||||
string path = Path.Combine(Program.AppDirectory, "audio");
|
string path = Path.Combine("audio", file);
|
||||||
path = Path.Combine(path, file);
|
Platform.WriteAllBytes(path, data);
|
||||||
File.WriteAllBytes(path, data);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,16 @@ namespace Launcher.Patcher {
|
|||||||
reader = new ZipReader();
|
reader = new ZipReader();
|
||||||
reader.SelectZipEntry = SelectZipEntry_Classic;
|
reader.SelectZipEntry = SelectZipEntry_Classic;
|
||||||
reader.ProcessZipEntry = ProcessZipEntry_Classic;
|
reader.ProcessZipEntry = ProcessZipEntry_Classic;
|
||||||
string texDir = Path.Combine(Program.AppDirectory, "texpacks");
|
string defPath = Path.Combine("texpacks", "default.zip");
|
||||||
string path = Path.Combine(texDir, "default.zip");
|
|
||||||
ExtractExisting(path);
|
|
||||||
|
|
||||||
using (Stream dst = new FileStream(path, FileMode.Create, FileAccess.Write)) {
|
if (Platform.FileExists(defPath)) {
|
||||||
|
using (Stream src = Platform.FileOpen(defPath)) {
|
||||||
|
reader.ProcessZipEntry = ExtractExisting;
|
||||||
|
reader.Extract(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using (Stream dst = Platform.FileCreate(defPath)) {
|
||||||
writer = new ZipWriter(dst);
|
writer = new ZipWriter(dst);
|
||||||
writer.entries = new ZipEntry[100];
|
writer.entries = new ZipEntry[100];
|
||||||
for (int i = 0; i < entries.Count; i++)
|
for (int i = 0; i < entries.Count; i++)
|
||||||
@ -60,14 +65,6 @@ namespace Launcher.Patcher {
|
|||||||
|
|
||||||
List<ZipEntry> entries = new List<ZipEntry>();
|
List<ZipEntry> entries = new List<ZipEntry>();
|
||||||
List<byte[]> datas = new List<byte[]>();
|
List<byte[]> datas = new List<byte[]>();
|
||||||
void ExtractExisting(string path) {
|
|
||||||
if (!File.Exists(path)) return;
|
|
||||||
|
|
||||||
using (Stream src = new FileStream(path, FileMode.Open, FileAccess.Read)) {
|
|
||||||
reader.ProcessZipEntry = ExtractExisting;
|
|
||||||
reader.Extract(src);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExtractExisting(string filename, byte[] data, ZipEntry entry) {
|
void ExtractExisting(string filename, byte[] data, ZipEntry entry) {
|
||||||
filename = ResourceList.GetFile(filename);
|
filename = ResourceList.GetFile(filename);
|
||||||
|
@ -57,10 +57,9 @@ namespace Launcher.Patcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DecodeSound(string name, byte[] rawData) {
|
void DecodeSound(string name, byte[] rawData) {
|
||||||
string path = Path.Combine(Program.AppDirectory, "audio");
|
string path = Path.Combine("audio", prefix + name + ".wav");
|
||||||
path = Path.Combine(path, prefix + name + ".wav");
|
|
||||||
|
|
||||||
using (FileStream dst = File.Create(path))
|
using (FileStream dst = Platform.FileCreate(path))
|
||||||
using (MemoryStream src = new MemoryStream(rawData))
|
using (MemoryStream src = new MemoryStream(rawData))
|
||||||
{
|
{
|
||||||
dst.SetLength(44);
|
dst.SetLength(44);
|
||||||
|
@ -10,22 +10,20 @@ namespace Launcher {
|
|||||||
|
|
||||||
public const string AppName = "ClassicalSharp Launcher 0.99.9.94";
|
public const string AppName = "ClassicalSharp Launcher 0.99.9.94";
|
||||||
|
|
||||||
public static string AppDirectory;
|
|
||||||
|
|
||||||
public static bool ShowingErrorDialog = false;
|
public static bool ShowingErrorDialog = false;
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
static void Main(string[] args) {
|
static void Main(string[] args) {
|
||||||
AppDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
Platform.AppDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
|
|
||||||
string path = Path.Combine(AppDirectory, "ClassicalSharp.exe");
|
if (!Platform.FileExists("ClassicalSharp.exe")) {
|
||||||
if (!File.Exists(path)) {
|
ErrorHandler.ShowDialog("Missing file", "ClassicalSharp.exe needs to be in the same folder as the launcher.");
|
||||||
Message("ClassicalSharp.exe needs to be in the same folder as the launcher."); return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
path = Path.Combine(AppDirectory, "OpenTK.dll");
|
if (!Platform.FileExists("OpenTK.dll")) {
|
||||||
if (!File.Exists(path)) {
|
ErrorHandler.ShowDialog("Missing file", "OpenTK.dll needs to be in the same folder as the launcher.");
|
||||||
Message("OpenTK.dll needs to be in the same folder as the launcher."); return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: we purposely put this in another method, as we need to ensure
|
// NOTE: we purposely put this in another method, as we need to ensure
|
||||||
@ -34,13 +32,9 @@ namespace Launcher {
|
|||||||
RunLauncher();
|
RunLauncher();
|
||||||
}
|
}
|
||||||
|
|
||||||
// put in separate function, because we don't want to load winforms assembly if possible
|
|
||||||
static void Message(string message) { MessageBox.Show(message, "Missing file"); }
|
|
||||||
|
|
||||||
static void RunLauncher() {
|
static void RunLauncher() {
|
||||||
string logPath = Path.Combine(AppDirectory, "launcher.log");
|
|
||||||
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
|
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
|
||||||
ErrorHandler.InstallHandler(logPath);
|
ErrorHandler.InstallHandler("launcher.log");
|
||||||
OpenTK.Configuration.SkipPerfCountersHack();
|
OpenTK.Configuration.SkipPerfCountersHack();
|
||||||
LauncherWindow window = new LauncherWindow();
|
LauncherWindow window = new LauncherWindow();
|
||||||
window.Run();
|
window.Run();
|
||||||
|
@ -27,16 +27,16 @@ namespace Launcher.Updater {
|
|||||||
ProcessStartInfo info = new ProcessStartInfo();
|
ProcessStartInfo info = new ProcessStartInfo();
|
||||||
info.CreateNoWindow = false;
|
info.CreateNoWindow = false;
|
||||||
info.UseShellExecute = true;
|
info.UseShellExecute = true;
|
||||||
info.WorkingDirectory = Program.AppDirectory;
|
info.WorkingDirectory = Platform.AppDirectory;
|
||||||
|
|
||||||
if (OpenTK.Configuration.RunningOnWindows) {
|
if (OpenTK.Configuration.RunningOnWindows) {
|
||||||
string path = Path.Combine(Program.AppDirectory, "update.bat");
|
Platform.WriteAllText("update.bat", Scripts.BatchFile);
|
||||||
File.WriteAllText(path, Scripts.BatchFile);
|
|
||||||
info.FileName = "cmd"; info.Arguments = "/C start cmd /C update.bat";
|
info.FileName = "cmd"; info.Arguments = "/C start cmd /C update.bat";
|
||||||
Process.Start(info);
|
Process.Start(info);
|
||||||
} else {
|
} else {
|
||||||
string path = Path.Combine(Program.AppDirectory, "update.sh");
|
string path = Path.Combine(Platform.AppDirectory, "update.sh");
|
||||||
File.WriteAllText(path, Scripts.BashFile.Replace("\r\n", "\n"));
|
Platform.WriteAllText("update.sh", Scripts.BashFile.Replace("\r\n", "\n"));
|
||||||
|
|
||||||
const int flags = 0x7;// read | write | executable
|
const int flags = 0x7;// read | write | executable
|
||||||
int code = chmod(path, (flags << 6) | (flags << 3) | 4);
|
int code = chmod(path, (flags << 6) | (flags << 3) | 4);
|
||||||
if (code != 0)
|
if (code != 0)
|
||||||
@ -55,23 +55,20 @@ namespace Launcher.Updater {
|
|||||||
internal static extern int chmod(string path, int mode);
|
internal static extern int chmod(string path, int mode);
|
||||||
|
|
||||||
static void MakeUpdatesFolder(byte[] zipData) {
|
static void MakeUpdatesFolder(byte[] zipData) {
|
||||||
|
Platform.DirectoryCreate("CS_Update");
|
||||||
using (MemoryStream stream = new MemoryStream(zipData)) {
|
using (MemoryStream stream = new MemoryStream(zipData)) {
|
||||||
ZipReader reader = new ZipReader();
|
ZipReader reader = new ZipReader();
|
||||||
string path = Path.Combine(Program.AppDirectory, "CS_Update");
|
|
||||||
Directory.CreateDirectory(path);
|
|
||||||
|
|
||||||
reader.ProcessZipEntry = ProcessZipEntry;
|
reader.ProcessZipEntry = ProcessZipEntry;
|
||||||
reader.Extract(stream);
|
reader.Extract(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessZipEntry(string filename, byte[] data, ZipEntry entry) {
|
static void ProcessZipEntry(string filename, byte[] data, ZipEntry entry) {
|
||||||
string path = Path.Combine(Program.AppDirectory, "CS_Update");
|
string path = Path.Combine("CS_Update", Path.GetFileName(filename));
|
||||||
path = Path.Combine(path, Path.GetFileName(filename));
|
Platform.WriteAllBytes(path, data);
|
||||||
File.WriteAllBytes(path, data);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File.SetLastWriteTimeUtc(path, PatchTime);
|
Platform.FileSetWriteTime(path, PatchTime);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
ErrorHandler.LogError("I/O exception when trying to set modified time for: " + filename, ex);
|
ErrorHandler.LogError("I/O exception when trying to set modified time for: " + filename, ex);
|
||||||
} catch (UnauthorizedAccessException ex) {
|
} catch (UnauthorizedAccessException ex) {
|
||||||
|
@ -28,15 +28,12 @@ namespace Launcher {
|
|||||||
return StartImpl(null, true, args, ref shouldExit);
|
return StartImpl(null, true, args, ref shouldExit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool StartImpl(ClientStartData data, bool classicubeSkins,
|
static bool StartImpl(ClientStartData data, bool ccSkins, string args, ref bool shouldExit) {
|
||||||
string args, ref bool shouldExit) {
|
if (!Platform.FileExists("ClassicalSharp.exe")) return false;
|
||||||
string path = Path.Combine(Program.AppDirectory, "ClassicalSharp.exe");
|
|
||||||
if (!File.Exists(path))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CheckSettings(data, classicubeSkins, out shouldExit);
|
CheckSettings(data, ccSkins, out shouldExit);
|
||||||
try {
|
try {
|
||||||
StartProcess(path, args);
|
StartProcess(args);
|
||||||
} catch (Win32Exception ex) {
|
} catch (Win32Exception ex) {
|
||||||
if ((uint)ex.ErrorCode != 0x80004005)
|
if ((uint)ex.ErrorCode != 0x80004005)
|
||||||
throw; // HRESULT when user clicks 'cancel' to 'are you sure you want to run ClassicalSharp.exe'
|
throw; // HRESULT when user clicks 'cancel' to 'are you sure you want to run ClassicalSharp.exe'
|
||||||
@ -46,7 +43,8 @@ namespace Launcher {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StartProcess(string path, string args) {
|
static void StartProcess(string args) {
|
||||||
|
string path = Path.Combine(Platform.AppDirectory, "ClassicalSharp.exe");
|
||||||
if (Configuration.RunningOnMono) {
|
if (Configuration.RunningOnMono) {
|
||||||
// We also need to handle the case of running Mono through wine
|
// We also need to handle the case of running Mono through wine
|
||||||
if (Configuration.RunningOnWindows) {
|
if (Configuration.RunningOnWindows) {
|
||||||
|
@ -80,7 +80,7 @@ void Chat_OpenLog(DateTime* now) {
|
|||||||
String_AppendConst(&path, ".log");
|
String_AppendConst(&path, ".log");
|
||||||
|
|
||||||
void* file;
|
void* file;
|
||||||
ReturnCode code = Platform_FileOpen(&file, &path, false);
|
ReturnCode code = Platform_FileAppend(&file, &path);
|
||||||
if (code != 0 && code != ReturnCode_FileShareViolation) {
|
if (code != 0 && code != ReturnCode_FileShareViolation) {
|
||||||
ErrorHandler_FailWithCode(code, "Chat - opening log file");
|
ErrorHandler_FailWithCode(code, "Chat - opening log file");
|
||||||
}
|
}
|
||||||
|
@ -13,4 +13,5 @@ void ErrorHandler_Log(STRING_PURE String* msg);
|
|||||||
void ErrorHandler_Fail(const UInt8* raw_msg);
|
void ErrorHandler_Fail(const UInt8* raw_msg);
|
||||||
void ErrorHandler_FailWithCode(ReturnCode returnCode, const UInt8* raw_msg);
|
void ErrorHandler_FailWithCode(ReturnCode returnCode, const UInt8* raw_msg);
|
||||||
#define ErrorHandler_CheckOrFail(returnCode, raw_msg) if (returnCode != 0) { ErrorHandler_FailWithCode(returnCode, raw_msg); }
|
#define ErrorHandler_CheckOrFail(returnCode, raw_msg) if (returnCode != 0) { ErrorHandler_FailWithCode(returnCode, raw_msg); }
|
||||||
|
void ErrorHandler_ShowDialog(const UInt8* title, const UInt8* msg);
|
||||||
#endif
|
#endif
|
@ -1275,7 +1275,7 @@ void LoadLevelScreen_EntryClick(GuiElement* screenElem, GuiElement* w) {
|
|||||||
if (!Platform_FileExists(&path)) return;
|
if (!Platform_FileExists(&path)) return;
|
||||||
|
|
||||||
void* file;
|
void* file;
|
||||||
ReturnCode code = Platform_FileOpen(&file, &path, true);
|
ReturnCode code = Platform_FileOpen(&file, &path);
|
||||||
ErrorHandler_CheckOrFail(code, "Failed to open map file");
|
ErrorHandler_CheckOrFail(code, "Failed to open map file");
|
||||||
Stream stream; Stream_FromFile(&stream, file, &path);
|
Stream stream; Stream_FromFile(&stream, file, &path);
|
||||||
|
|
||||||
@ -1504,7 +1504,7 @@ void ClassicHacksKeyBindingsScreen_ContextRecreated(void* obj) {
|
|||||||
KeyBindingsScreen_MakeWidgets(screen, -90, -40, 3, "Hacks controls", 260);
|
KeyBindingsScreen_MakeWidgets(screen, -90, -40, 3, "Hacks controls", 260);
|
||||||
}
|
}
|
||||||
|
|
||||||
Screen* ClassicHackKeyBindingsScreen_MakeInstance(void) {
|
Screen* ClassicHacksKeyBindingsScreen_MakeInstance(void) {
|
||||||
static KeyBind binds[6] = { KeyBind_Speed, KeyBind_NoClip, KeyBind_HalfSpeed, KeyBind_Fly, KeyBind_FlyUp, KeyBind_FlyDown };
|
static KeyBind binds[6] = { KeyBind_Speed, KeyBind_NoClip, KeyBind_HalfSpeed, KeyBind_Fly, KeyBind_FlyUp, KeyBind_FlyDown };
|
||||||
static const UInt8* descs[6] = { "Speed", "Noclip", "Half speed", "Fly", "Fly up", "Fly down" };
|
static const UInt8* descs[6] = { "Speed", "Noclip", "Half speed", "Fly", "Fly up", "Fly down" };
|
||||||
static ButtonWidget buttons[6];
|
static ButtonWidget buttons[6];
|
||||||
|
@ -141,7 +141,7 @@ void Options_Set(const UInt8* keyRaw, STRING_PURE String* value) {
|
|||||||
void Options_Load(void) {
|
void Options_Load(void) {
|
||||||
void* file = NULL;
|
void* file = NULL;
|
||||||
String path = String_FromConst("options.txt");
|
String path = String_FromConst("options.txt");
|
||||||
ReturnCode result = Platform_FileOpen(&file, &path, true);
|
ReturnCode result = Platform_FileOpen(&file, &path);
|
||||||
|
|
||||||
if (result == ReturnCode_FileNotFound) return;
|
if (result == ReturnCode_FileNotFound) return;
|
||||||
/* TODO: Should we just log failure to open? */
|
/* TODO: Should we just log failure to open? */
|
||||||
@ -182,7 +182,7 @@ void Options_Load(void) {
|
|||||||
void Options_Save(void) {
|
void Options_Save(void) {
|
||||||
void* file = NULL;
|
void* file = NULL;
|
||||||
String path = String_FromConst("options.txt");
|
String path = String_FromConst("options.txt");
|
||||||
ReturnCode result = Platform_FileOpen(&file, &path, true);
|
ReturnCode result = Platform_FileOpen(&file, &path);
|
||||||
|
|
||||||
/* TODO: Should we just log failure to save? */
|
/* TODO: Should we just log failure to save? */
|
||||||
ErrorHandler_CheckOrFail(result, "Options - Saving");
|
ErrorHandler_CheckOrFail(result, "Options - Saving");
|
||||||
|
@ -31,7 +31,8 @@ typedef void Platform_EnumFilesCallback(STRING_PURE String* path, void* obj);
|
|||||||
ReturnCode Platform_EnumFiles(STRING_PURE String* path, void* obj, Platform_EnumFilesCallback callback);
|
ReturnCode Platform_EnumFiles(STRING_PURE String* path, void* obj, Platform_EnumFilesCallback callback);
|
||||||
|
|
||||||
ReturnCode Platform_FileCreate(void** file, STRING_PURE String* path);
|
ReturnCode Platform_FileCreate(void** file, STRING_PURE String* path);
|
||||||
ReturnCode Platform_FileOpen(void** file, STRING_PURE String* path, bool readOnly);
|
ReturnCode Platform_FileOpen(void** file, STRING_PURE String* path);
|
||||||
|
ReturnCode Platform_FileAppend(void** file, STRING_PURE String* path);
|
||||||
ReturnCode Platform_FileRead(void* file, UInt8* buffer, UInt32 count, UInt32* bytesRead);
|
ReturnCode Platform_FileRead(void* file, UInt8* buffer, UInt32 count, UInt32* bytesRead);
|
||||||
ReturnCode Platform_FileWrite(void* file, UInt8* buffer, UInt32 count, UInt32* bytesWritten);
|
ReturnCode Platform_FileWrite(void* file, UInt8* buffer, UInt32 count, UInt32* bytesWritten);
|
||||||
ReturnCode Platform_FileClose(void* file);
|
ReturnCode Platform_FileClose(void* file);
|
||||||
|
@ -24,7 +24,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
/*void* file;
|
/*void* file;
|
||||||
String path = String_FromConstant("H:\\PortableApps\\GitPortable\\App\\Git\\ClassicalSharp\\output\\release\\texpacks\\skybox.png");
|
String path = String_FromConstant("H:\\PortableApps\\GitPortable\\App\\Git\\ClassicalSharp\\output\\release\\texpacks\\skybox.png");
|
||||||
ReturnCode openCode = Platform_FileOpen(&file, &path, true);
|
ReturnCode openCode = Platform_FileOpen(&file, &path);
|
||||||
Stream fileStream;
|
Stream fileStream;
|
||||||
Stream_FromFile(&fileStream, file, &path);
|
Stream_FromFile(&fileStream, file, &path);
|
||||||
Bitmap bmp;
|
Bitmap bmp;
|
||||||
@ -61,7 +61,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
/*void* file;
|
/*void* file;
|
||||||
String path = String_FromConstant("H:\\PortableApps\\GitPortable\\App\\Git\\ClassicalSharp\\output\\release\\texpacks\\default.zip");
|
String path = String_FromConstant("H:\\PortableApps\\GitPortable\\App\\Git\\ClassicalSharp\\output\\release\\texpacks\\default.zip");
|
||||||
ReturnCode openCode = Platform_FileOpen(&file, &path, true);
|
ReturnCode openCode = Platform_FileOpen(&file, &path);
|
||||||
Stream fileStream;
|
Stream fileStream;
|
||||||
Stream_FromFile(&fileStream, file, &path);
|
Stream_FromFile(&fileStream, file, &path);
|
||||||
ZipState state;
|
ZipState state;
|
||||||
@ -71,7 +71,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
void* file;
|
void* file;
|
||||||
String path = String_FromConst("H:\\PortableApps\\GitPortable\\App\\Git\\ClassicalSharp\\src\\x64\\Release\\canyon.lvl");
|
String path = String_FromConst("H:\\PortableApps\\GitPortable\\App\\Git\\ClassicalSharp\\src\\x64\\Release\\canyon.lvl");
|
||||||
ReturnCode openCode = Platform_FileOpen(&file, &path, true);
|
ReturnCode openCode = Platform_FileOpen(&file, &path);
|
||||||
Stream fileStream;
|
Stream fileStream;
|
||||||
Stream_FromFile(&fileStream, file, &path);
|
Stream_FromFile(&fileStream, file, &path);
|
||||||
Lvl_Load(&fileStream);
|
Lvl_Load(&fileStream);
|
||||||
@ -79,7 +79,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
/*void* file;
|
/*void* file;
|
||||||
String path = String_FromConstant("H:\\PortableApps\\GitPortable\\App\\Git\\\ClassicalSharp\\src\\Debug\\gunzip.c.gz");
|
String path = String_FromConstant("H:\\PortableApps\\GitPortable\\App\\Git\\\ClassicalSharp\\src\\Debug\\gunzip.c.gz");
|
||||||
ReturnCode openCode = Platform_FileOpen(&file, &path, true);
|
ReturnCode openCode = Platform_FileOpen(&file, &path);
|
||||||
Stream fileStream;
|
Stream fileStream;
|
||||||
Stream_FromFile(&fileStream, file, &path);
|
Stream_FromFile(&fileStream, file, &path);
|
||||||
|
|
||||||
|
@ -32,8 +32,7 @@ void ErrorHandler_Fail(const UInt8* raw_msg) {
|
|||||||
ErrorHandler_WriteLogBody(raw_msg);
|
ErrorHandler_WriteLogBody(raw_msg);
|
||||||
ErrorHandler_WriteLogEnd();
|
ErrorHandler_WriteLogEnd();
|
||||||
|
|
||||||
HWND win = GetActiveWindow();
|
ErrorHandler_ShowDialog("We're sorry", logMsg.buffer);
|
||||||
MessageBoxA(win, logMsg.buffer, "We're sorry", 0);
|
|
||||||
ExitProcess(1);
|
ExitProcess(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +44,11 @@ void ErrorHandler_FailWithCode(ReturnCode code, const UInt8* raw_msg) {
|
|||||||
String_AppendConst(&logMsg, "\r\n");
|
String_AppendConst(&logMsg, "\r\n");
|
||||||
ErrorHandler_WriteLogEnd();
|
ErrorHandler_WriteLogEnd();
|
||||||
|
|
||||||
HWND win = GetActiveWindow(); /* TODO: It's probably wrong to use GetActiveWindow() here */
|
ErrorHandler_ShowDialog("We're sorry", logMsg.buffer);
|
||||||
MessageBoxA(win, logMsg.buffer, "We're sorry", 0);
|
|
||||||
ExitProcess(code);
|
ExitProcess(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ErrorHandler_ShowDialog(const UInt8* title, const UInt8* msg) {
|
||||||
|
HWND win = GetActiveWindow(); /* TODO: It's probably wrong to use GetActiveWindow() here */
|
||||||
|
MessageBoxA(win, msg, title, 0);
|
||||||
|
}
|
@ -151,23 +151,28 @@ ReturnCode Platform_EnumFiles(STRING_PURE String* path, void* obj, Platform_Enum
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ReturnCode Platform_FileOpen(void** file, STRING_PURE String* path, bool readOnly) {
|
ReturnCode Platform_FileOpen(void** file, STRING_PURE String* path) {
|
||||||
UINT32 access = GENERIC_READ;
|
HANDLE handle = CreateFileA(path->buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
if (!readOnly) access |= GENERIC_WRITE;
|
|
||||||
HANDLE handle = CreateFileA(path->buffer, access, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
*file = (void*)handle;
|
*file = (void*)handle;
|
||||||
|
|
||||||
return handle != INVALID_HANDLE_VALUE ? 0 : GetLastError();
|
return handle != INVALID_HANDLE_VALUE ? 0 : GetLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode Platform_FileCreate(void** file, STRING_PURE String* path) {
|
ReturnCode Platform_FileCreate(void** file, STRING_PURE String* path) {
|
||||||
UINT32 access = GENERIC_READ | GENERIC_WRITE;
|
HANDLE handle = CreateFileA(path->buffer, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
HANDLE handle = CreateFileA(path->buffer, access, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
*file = (void*)handle;
|
*file = (void*)handle;
|
||||||
|
|
||||||
return handle != INVALID_HANDLE_VALUE ? 0 : GetLastError();
|
return handle != INVALID_HANDLE_VALUE ? 0 : GetLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnCode Platform_FileAppend(void** file, STRING_PURE String* path) {
|
||||||
|
HANDLE handle = CreateFileA(path->buffer, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
*file = (void*)handle;
|
||||||
|
|
||||||
|
if (handle == INVALID_HANDLE_VALUE) return GetLastError();
|
||||||
|
return Platform_FileSeek(*file, 0, STREAM_SEEKFROM_END);
|
||||||
|
}
|
||||||
|
|
||||||
ReturnCode Platform_FileRead(void* file, UInt8* buffer, UInt32 count, UInt32* bytesRead) {
|
ReturnCode Platform_FileRead(void* file, UInt8* buffer, UInt32 count, UInt32* bytesRead) {
|
||||||
BOOL success = ReadFile((HANDLE)file, buffer, count, bytesRead, NULL);
|
BOOL success = ReadFile((HANDLE)file, buffer, count, bytesRead, NULL);
|
||||||
return success ? 0 : GetLastError();
|
return success ? 0 : GetLastError();
|
||||||
@ -187,11 +192,11 @@ ReturnCode Platform_FileSeek(void* file, Int32 offset, Int32 seekType) {
|
|||||||
DWORD pos;
|
DWORD pos;
|
||||||
switch (seekType) {
|
switch (seekType) {
|
||||||
case STREAM_SEEKFROM_BEGIN:
|
case STREAM_SEEKFROM_BEGIN:
|
||||||
pos = SetFilePointer(file, offset, NULL, 0); break;
|
pos = SetFilePointer(file, offset, NULL, FILE_BEGIN); break;
|
||||||
case STREAM_SEEKFROM_CURRENT:
|
case STREAM_SEEKFROM_CURRENT:
|
||||||
pos = SetFilePointer(file, offset, NULL, 1); break;
|
pos = SetFilePointer(file, offset, NULL, FILE_CURRENT); break;
|
||||||
case STREAM_SEEKFROM_END:
|
case STREAM_SEEKFROM_END:
|
||||||
pos = SetFilePointer(file, offset, NULL, 2); break;
|
pos = SetFilePointer(file, offset, NULL, FILE_END); break;
|
||||||
default:
|
default:
|
||||||
ErrorHandler_Fail("Invalid SeekType provided when seeking file");
|
ErrorHandler_Fail("Invalid SeekType provided when seeking file");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user