redesign how file and directory methods work

This commit is contained in:
UnknownShadow200 2018-04-14 15:37:20 +10:00
parent c68eb4df4b
commit 533cca344f
42 changed files with 343 additions and 295 deletions

View File

@ -13,15 +13,13 @@ namespace ClassicalSharp.Gui.Screens {
public LoadLevelScreen(Game game) : base(game) {
titleText = "Select a level";
string dir = Path.Combine(Program.AppDirectory, "maps");
string[] rawFiles = Directory.GetFiles(dir);
string[] rawFiles = Platform.DirectoryFiles("maps");
int count = 0;
// Only add map files
for (int i = 0; i < rawFiles.Length; i++) {
string file = rawFiles[i];
if (file.EndsWith(".cw") || file.EndsWith(".dat")
|| file.EndsWith(".fcm") || file.EndsWith(".lvl")) {
if (file.EndsWith(".cw") || file.EndsWith(".dat") || file.EndsWith(".fcm") || file.EndsWith(".lvl")) {
count++;
} else {
rawFiles[i] = null;
@ -38,13 +36,9 @@ namespace ClassicalSharp.Gui.Screens {
}
protected override void TextButtonClick(Game game, Widget widget) {
string path = Path.Combine(Program.AppDirectory, "maps");
path = Path.Combine(path, ((ButtonWidget)widget).Text);
if (File.Exists(path))
LoadMap(path);
}
string path = Path.Combine("maps", ((ButtonWidget)widget).Text);
if (!Platform.FileExists(path)) return;
void LoadMap(string path) {
IMapFormatImporter importer = null;
if (path.EndsWith(".dat")) {
importer = new MapDatImporter();
@ -57,7 +51,7 @@ namespace ClassicalSharp.Gui.Screens {
}
try {
using (FileStream fs = File.OpenRead(path)) {
using (Stream fs = Platform.FileOpen(path)) {
int width, height, length;
game.World.Reset();
game.WorldEvents.RaiseOnNewMap();

View File

@ -15,14 +15,30 @@ namespace ClassicalSharp.Gui.Screens {
InputWidget input;
const int overwriteIndex = 2;
static FastColour grey = new FastColour(150, 150, 150);
string textPath;
public override void Render(double delta) {
base.Render(delta);
int cX = game.Width / 2, cY = game.Height / 2;
game.Graphics.Draw2DQuad(cX - 250, cY + 90, 500, 2, grey);
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;
}
@ -79,23 +95,23 @@ namespace ClassicalSharp.Gui.Screens {
void SaveSchematic(Game game, Widget widget) { DoSave(widget, ".schematic"); }
void DoSave(Widget widget, string ext) {
string text = input.Text.ToString();
if (text.Length == 0) {
string file = input.Text.ToString();
if (file.Length == 0) {
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;
if (File.Exists(text) && btn.OptName == null) {
if (Platform.FileExists(path) && btn.OptName == null) {
btn.SetText("&cOverwrite existing?");
btn.OptName = "O";
} else {
// 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.
MakeDescWidget("Saving..");
textPath = text;
textPath = path;
RemoveOverwrites();
}
}
@ -113,27 +129,6 @@ namespace ClassicalSharp.Gui.Screens {
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) {
DisposeDescWidget();
widgets[widgets.Length - 1] = TextWidget.Create(game, text, textFont)

View File

@ -10,19 +10,18 @@ namespace ClassicalSharp.Gui.Screens {
public TexturePackScreen(Game game) : base(game) {
titleText = "Select a texture pack zip";
string dir = Path.Combine(Program.AppDirectory, "texpacks");
entries = Directory.GetFiles(dir, "*.zip");
entries = Platform.DirectoryFiles("texpacks", "*.zip");
for (int i = 0; i < entries.Length; i++)
for (int i = 0; i < entries.Length; i++) {
entries[i] = Path.GetFileName(entries[i]);
}
Array.Sort(entries);
}
protected override void TextButtonClick(Game game, Widget widget) {
string file = ((ButtonWidget)widget).Text;
string dir = Path.Combine(Program.AppDirectory, "texpacks");
string path = Path.Combine(dir, file);
if (!File.Exists(path)) return;
string path = Path.Combine("texpacks", file);
if (!Platform.FileExists(path)) return;
int curPage = currentIndex;
game.DefaultTexturePack = file;

View File

@ -17,11 +17,11 @@ namespace ClassicalSharp.Audio {
public void Init(Game game) {
this.game = game;
string path = Path.Combine(Program.AppDirectory, "audio");
if (Directory.Exists(path))
files = Directory.GetFiles(path);
else
if (Platform.DirectoryExists("audio")) {
files = Platform.DirectoryFiles("audio");
} else {
files = new string[0];
}
game.MusicVolume = GetVolume(OptionsKey.MusicVolume, OptionsKey.UseMusic);
SetMusic(game.MusicVolume);
@ -60,7 +60,8 @@ namespace ClassicalSharp.Audio {
musicFiles = new string[musicCount];
for (int i = 0, j = 0; i < files.Length; i++) {
if (!Utils.CaselessEnds(files[i], ".ogg")) continue;
musicFiles[j] = files[i]; j++;
musicFiles[j] = Path.GetFileName(files[i]);
j++;
}
disposingMusic = false;
@ -75,10 +76,9 @@ namespace ClassicalSharp.Audio {
Random rnd = new Random();
while (!disposingMusic) {
string file = musicFiles[rnd.Next(0, musicFiles.Length)];
string path = Path.Combine(Program.AppDirectory, file);
Utils.LogDebug("playing music file: " + file);
using (FileStream fs = File.OpenRead(path)) {
using (Stream fs = Platform.FileOpen(file)) {
OggContainer container = new OggContainer(fs);
try {
musicOut.SetVolume(game.MusicVolume / 100.0f);

View File

@ -65,7 +65,7 @@ namespace ClassicalSharp.Audio {
}
Sound ReadWave(string file) {
using (FileStream fs = File.OpenRead(file))
using (Stream fs = File.OpenRead(file))
using (BinaryReader r = new BinaryReader(fs))
{
string fourCC = GetFourCC(r);

View File

@ -126,20 +126,19 @@ namespace ClassicalSharp {
}
void OpenChatFile(DateTime now) {
string basePath = Path.Combine(Program.AppDirectory, "logs");
if (!Directory.Exists(basePath))
Directory.CreateDirectory(basePath);
if (!Platform.DirectoryExists("logs")) {
Platform.DirectoryCreate("logs");
}
string date = now.ToString("yyyy-MM-dd");
// Ensure multiple instances do not end up overwriting each other's log entries.
for (int i = 0; i < 20; i++) {
string id = i == 0 ? "" : " _" + i;
string fileName = date + " " + logName + id + ".log";
string path = Path.Combine(basePath, fileName);
string path = Path.Combine("logs", date + " " + logName + id + ".log");
FileStream stream = null;
Stream stream = null;
try {
stream = File.Open(path, FileMode.Append, FileAccess.Write, FileShare.Read);
stream = Platform.FileAppend(path);
} catch (IOException ex) {
int hresult = Marshal.GetHRForException(ex);
uint errorCode = (uint)hresult & 0xFFFF;

View File

@ -161,9 +161,12 @@ namespace ClassicalSharp {
defTexturePack = Options.Get(OptionsKey.DefaultTexturePack) ?? "default.zip";
TexturePack extractor = new TexturePack();
extractor.Extract("default.zip", this);
// in case the user's default texture pack doesn't have all required textures
if (DefaultTexturePack != "default.zip")
extractor.Extract(DefaultTexturePack, this);
string defTexPack = DefaultTexturePack;
if (defTexPack != "default.zip") {
extractor.Extract(defTexPack, this);
}
}
void LoadOptions() {

View File

@ -9,7 +9,6 @@ using ClassicalSharp.Commands;
using ClassicalSharp.Entities;
using ClassicalSharp.Events;
using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Gui;
using ClassicalSharp.Map;
using ClassicalSharp.Mode;
using ClassicalSharp.Model;
@ -231,9 +230,8 @@ namespace ClassicalSharp {
/// this method returns "default.zip". </remarks>
public string DefaultTexturePack {
get {
string path = Path.Combine(Program.AppDirectory, "texpacks");
path = Path.Combine(path, defTexturePack);
return File.Exists(path) && !ClassicMode ? defTexturePack : "default.zip";
string texPath = Path.Combine("texpacks", defTexturePack);
return Platform.FileExists(texPath) && !ClassicMode ? defTexturePack : "default.zip";
}
set {
defTexturePack = value;

View File

@ -202,13 +202,14 @@ namespace ClassicalSharp {
}
void TakeScreenshot() {
string path = PathIO.Combine(Program.AppDirectory, "screenshots");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
if (!Platform.DirectoryExists("screenshots")) {
Platform.DirectoryCreate("screenshots");
}
string timestamp = DateTime.Now.ToString("dd-MM-yyyy-HH-mm-ss");
string file = "screenshot_" + timestamp + ".png";
path = PathIO.Combine(path, file);
string path = PathIO.Combine("screenshots", file);
Graphics.TakeScreenshot(path, Width, Height);
Chat.Add("&eTaken screenshot as: " + file);
screenshotRequested = false;

View File

@ -21,20 +21,20 @@ namespace ClassicalSharp {
internal static Game game;
internal static List<string> LoadAll() {
string dir = Path.Combine(Program.AppDirectory, "plugins");
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
if (!Platform.DirectoryExists("plugins")) {
Platform.DirectoryCreate("plugins");
}
Accepted = new EntryList("plugins", "accepted.txt");
Denied = new EntryList("plugins", "denied.txt");
Accepted.Load();
Denied.Load();
return LoadPlugins(dir);
return LoadPlugins();
}
static List<string> LoadPlugins(string dir) {
string[] dlls = Directory.GetFiles(dir, "*.dll");
static List<string> LoadPlugins() {
string[] dlls = Platform.DirectoryFiles("plugins", "*.dll");
List<string> nonLoaded = null;
for (int i = 0; i < dlls.Length; i++) {
@ -55,8 +55,7 @@ namespace ClassicalSharp {
public static void Load(string pluginName, bool needsInit) {
try {
string dir = Path.Combine(Program.AppDirectory, "plugins");
string path = Path.Combine(dir, pluginName + ".dll");
string path = Path.Combine("plguins", pluginName + ".dll");
Assembly lib = Assembly.LoadFrom(path);
Type[] types = lib.GetTypes();

View File

@ -3,6 +3,7 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using OpenTK;
@ -553,9 +554,10 @@ namespace ClassicalSharp.GraphicsAPI {
device.GetRenderTargetData(backbuffer, tempSurface);
LockedRectangle rect = tempSurface.LockRectangle(LockFlags.ReadOnly | LockFlags.NoDirtyUpdate);
using (Bitmap bmp = new Bitmap(width, height, width * sizeof(int),
PixelFormat.Format32bppRgb, rect.DataPointer)) {
bmp.Save(output, ImageFormat.Png);
using (Bitmap bmp = new Bitmap(width, height, width * sizeof(int), PixelFormat.Format32bppRgb, rect.DataPointer)) {
using (Stream fs = Platform.FileCreate(output)) {
Platform.WriteBmp(bmp, fs);
}
}
tempSurface.UnlockRectangle();
}

View File

@ -3,6 +3,7 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using OpenTK;
using OpenTK.Graphics.OpenGL;
@ -551,7 +552,10 @@ namespace ClassicalSharp.GraphicsAPI {
using (FastBitmap fastBmp = new FastBitmap(bmp, true, false))
GL.ReadPixels(0, 0, width, height, GlPixelFormat.Bgra, PixelType.UnsignedByte, fastBmp.Scan0);
bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
bmp.Save(output, ImageFormat.Png);
using (Stream fs = Platform.FileCreate(output)) {
Platform.WriteBmp(bmp, fs);
}
}
}

View File

@ -342,10 +342,11 @@ namespace ClassicalSharp.GraphicsAPI {
}
}
}
using (FileStream fs = File.Create(output))
using (Stream fs = Platform.FileCreate(output)) {
Platform.WriteBmp(bmp, fs);
}
}
}
public override void OnWindowResize(Game game) {
GL.Viewport(0, 0, game.Width, game.Height);

View File

@ -74,12 +74,12 @@ namespace ClassicalSharp {
internal void DownloadTexturePack(string url) {
if (game.DeniedUrls.Has(url)) return;
string path = TextureCache.MakePath(url), etag = null;
string etag = null;
DateTime lastModified = DateTime.MinValue;
if (File.Exists(path)) {
lastModified = TextureCache.GetLastModified(url, path, game.LastModified);
etag = TextureCache.GetETag(url, path, game.ETags);
if (TextureCache.HasUrl(url)) {
lastModified = TextureCache.GetLastModified(url, game.LastModified);
etag = TextureCache.GetETag(url, game.ETags);
}
TexturePack.ExtractCurrent(game, url);

View File

@ -41,13 +41,14 @@ namespace ClassicalSharp {
}
public void LoadIcon() {
string launcherPath = Path.Combine(Program.AppDirectory, "Launcher2.exe");
if (!File.Exists(launcherPath)) {
launcherPath = Path.Combine(Program.AppDirectory, "Launcher.exe");
string launcherFile = "Launcher2.exe";
if (!Platform.FileExists(launcherFile)) {
launcherFile = "Launcher.exe";
}
if (!File.Exists(launcherPath)) return;
if (!Platform.FileExists(launcherFile)) return;
try {
string launcherPath = Path.Combine(Platform.AppDirectory, launcherFile);
Icon = Icon.ExtractAssociatedIcon(launcherPath);
} catch (Exception ex) {
ErrorHandler.LogError("DesktopWindow.LoadIcon()", ex);

View File

@ -13,6 +13,8 @@ namespace ClassicalSharp {
/// <summary> Abstracts away platform specific operations. </summary>
public static class Platform {
public static string AppDirectory;
public static bool ValidBitmap(Bitmap bmp) {
// 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.
@ -70,5 +72,65 @@ namespace ClassicalSharp {
return config != null && config == Bitmap.Config.Argb8888;
#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);
}
}
}

View File

@ -3,7 +3,6 @@ using System;
using System.IO;
using System.Net;
using System.Windows.Forms;
using ClassicalSharp.Textures;
using OpenTK;
namespace ClassicalSharp {
@ -12,21 +11,21 @@ namespace ClassicalSharp {
public const string AppName = "ClassicalSharp 0.99.9.94";
public static string AppDirectory;
#if !LAUNCHER
[STAThread]
static void Main(string[] args) {
AppDirectory = AppDomain.CurrentDomain.BaseDirectory;
Platform.AppDirectory = AppDomain.CurrentDomain.BaseDirectory;
CleanupMainDirectory();
string path = Path.Combine(Program.AppDirectory, "texpacks");
if (!File.Exists(Path.Combine(path, "default.zip"))) {
Message("default.zip not found, try running the launcher first."); return;
string defPath = Path.Combine("texpacks", "default.zip");
if (!Platform.FileExists(defPath)) {
ErrorHandler.ShowDialog("Missing file", "default.zip not found, try running the launcher first.");
return;
}
path = Path.Combine(AppDirectory, "OpenTK.dll");
if (!File.Exists(path)) {
Message("OpenTK.dll needs to be in the same folder as the game"); return;
if (!Platform.FileExists("OpenTK.dll")) {
ErrorHandler.ShowDialog("Missing file", "OpenTK.dll needs to be in the same folder as the game");
return;
}
// NOTE: we purposely put this in another method, as we need to ensure
@ -36,8 +35,7 @@ namespace ClassicalSharp {
}
static void RunGame(string[] args) {
string logPath = Path.Combine(AppDirectory, "client.log");
ErrorHandler.InstallHandler(logPath);
ErrorHandler.InstallHandler("client.log");
OpenTK.Configuration.SkipPerfCountersHack();
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) {
IPAddress ip = null;
if (!IPAddress.TryParse(args[2], out ip)) {
@ -97,14 +92,14 @@ namespace ClassicalSharp {
}
#endif
internal static void CleanupMainDirectory() {
string mapPath = Path.Combine(Program.AppDirectory, "maps");
if (!Directory.Exists(mapPath))
Directory.CreateDirectory(mapPath);
public static void CleanupMainDirectory() {
if (!Platform.DirectoryExists("maps")) {
Platform.DirectoryCreate("maps");
}
string texPath = Path.Combine(Program.AppDirectory, "texpacks");
if (!Directory.Exists(texPath))
Directory.CreateDirectory(texPath);
if (!Platform.DirectoryExists("texpacks")) {
Platform.DirectoryCreate("texpacks");
}
}
}
}

View File

@ -43,7 +43,7 @@ namespace ClassicalSharp.Textures {
animsBuffer = new FastBitmap(animBmp, true, true);
} else if (e.Name == "animations.txt" || e.Name == "animation.txt") {
MemoryStream stream = new MemoryStream(e.Data);
StreamReader reader = new StreamReader(stream);
StreamReader reader = new StreamReader(stream, false);
ReadAnimationsDescription(reader);
} else if (e.Name == "uselavaanim") {
useLavaAnim = true;

View File

@ -25,12 +25,11 @@ namespace ClassicalSharp.Textures {
}
public bool Load() {
string path = Path.Combine(Program.AppDirectory, folder);
path = Path.Combine(path, file);
if (!File.Exists(path)) return true;
string path = Path.Combine(folder, file);
if (!Platform.FileExists(path)) return true;
try {
using (Stream fs = File.OpenRead(path))
using (Stream fs = Platform.FileOpen(path))
using (StreamReader reader = new StreamReader(fs, false))
{
string line;
@ -49,11 +48,12 @@ namespace ClassicalSharp.Textures {
public bool Save() {
try {
string path = Path.Combine(Program.AppDirectory, folder);
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
if (!Platform.DirectoryExists(folder)) {
Platform.DirectoryCreate(folder);
}
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))
{
for (int i = 0; i < Entries.Count; i++)

View File

@ -14,18 +14,16 @@ namespace ClassicalSharp.Textures {
public static class TextureCache {
/// <summary> Gets whether the given url has data associated with it in the cache. </summary>
public static bool HasUrl(string url) {
return File.Exists(MakePath(url));
}
public static bool HasUrl(string url) { return Platform.FileExists(MakePath(url)); }
/// <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>
public static FileStream GetStream(string url) {
string path = MakePath(url);
if (!File.Exists(path)) return null;
if (!Platform.FileExists(path)) return null;
try {
return File.OpenRead(path);
return Platform.FileOpen(path);
} catch (IOException ex) {
ErrorHandler.LogError("Cache.GetData", ex);
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,
/// 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);
long ticks = 0;
if (entry != null && long.TryParse(entry, out ticks)) {
return new DateTime(ticks, DateTimeKind.Utc);
} 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);
}
@ -67,12 +66,13 @@ namespace ClassicalSharp.Textures {
public static void Add(string url, Bitmap bmp) {
string path = MakePath(url);
try {
string basePath = PathIO.Combine(Program.AppDirectory, Folder);
if (!Directory.Exists(basePath))
Directory.CreateDirectory(basePath);
if (!Platform.DirectoryExists(Folder)) {
Platform.DirectoryCreate(Folder);
}
using (FileStream fs = File.Create(path))
using (Stream fs = Platform.FileCreate(path)) {
Platform.WriteBmp(bmp, fs);
}
} catch (IOException ex) {
ErrorHandler.LogError("Cache.AddToCache", ex);
}
@ -82,10 +82,11 @@ namespace ClassicalSharp.Textures {
public static void Add(string url, byte[] data) {
string path = MakePath(url);
try {
string basePath = PathIO.Combine(Program.AppDirectory, Folder);
if (!Directory.Exists(basePath))
Directory.CreateDirectory(basePath);
File.WriteAllBytes(path, data);
if (!Platform.DirectoryExists(Folder)) {
Platform.DirectoryCreate(Folder);
}
Platform.WriteAllBytes(path, data);
} catch (IOException ex) {
ErrorHandler.LogError("Cache.AddToCache", ex);
}
@ -114,12 +115,7 @@ namespace ClassicalSharp.Textures {
const string Folder = "texturecache";
public static string MakePath(string url) {
string crc32 = CRC32(url);
string basePath = PathIO.Combine(Program.AppDirectory, Folder);
return PathIO.Combine(basePath, crc32);
}
public static string MakePath(string url) { return PathIO.Combine(Folder, CRC32(url)); }
static string CRC32(string url) {
byte[] data = Encoding.UTF8.GetBytes(url);

View File

@ -17,12 +17,12 @@ namespace ClassicalSharp.Textures {
Game game;
public void Extract(string path, Game game) {
path = PathIO.Combine("texpacks", path);
path = PathIO.Combine(Program.AppDirectory, path);
using (Stream fs = File.OpenRead(path))
public void Extract(string file, Game game) {
string path = PathIO.Combine("texpacks", file);
using (Stream fs = Platform.FileOpen(path)) {
Extract(fs, game);
}
}
public void Extract(Stream stream, Game game) {
this.game = game;

View File

@ -11,14 +11,12 @@ namespace ClassicalSharp {
/// and also logs it to a specified log file. </summary>
public static class ErrorHandler {
static string logFile = "crash.log";
static string fileName = "crash.log";
/// <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>
public static void InstallHandler(string logFile) {
ErrorHandler.logFile = logFile;
fileName = Path.GetFileName(logFile);
fileName = logFile;
if (!Debugger.IsAttached)
AppDomain.CurrentDomain.UnhandledException += UnhandledException;
}
@ -40,7 +38,9 @@ namespace ClassicalSharp {
Exception ex = (Exception)e.ExceptionObject;
bool wroteToCrashLog = true;
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("Time: " + DateTime.Now);
@ -72,12 +72,12 @@ namespace ClassicalSharp {
string line1 = "ClassicalSharp crashed.";
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.";
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);
}
@ -93,16 +93,23 @@ namespace ClassicalSharp {
/// <summary> Logs an error that occured at the specified location to the log file. </summary>
public static bool LogError(string location, string text) {
try {
using (StreamWriter writer = new StreamWriter(logFile, true)) {
writer.WriteLine("=== handled error ===");
writer.WriteLine("Occured when: " + location);
writer.WriteLine(text);
writer.WriteLine();
using (Stream fs = Platform.FileAppend(fileName))
using (StreamWriter w = new StreamWriter(fs))
{
w.WriteLine("=== handled error ===");
w.WriteLine("Occured when: " + location);
w.WriteLine(text);
w.WriteLine();
}
} catch (Exception) {
return false;
}
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);
}
}
}

View File

@ -190,14 +190,8 @@ namespace ClassicalSharp {
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 {
string path = Path.Combine(Program.AppDirectory, Filename);
using (Stream fs = File.OpenRead(path))
using (Stream fs = Platform.FileOpen(Filename))
using (StreamReader reader = new StreamReader(fs, false))
{
LoadFrom(reader);
@ -239,8 +233,7 @@ namespace ClassicalSharp {
public static bool Save() {
try {
string path = Path.Combine(Program.AppDirectory, Filename);
using (Stream fs = File.Create(path))
using (Stream fs = Platform.FileCreate(Filename))
using (StreamWriter writer = new StreamWriter(fs))
{
SaveTo(writer);

View File

@ -1,6 +1,6 @@
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
using System;
using System.IO;
using ClassicalSharp;
using ClassicalSharp.Network;
using Launcher.Gui.Views;
using Launcher.Patcher;
@ -90,7 +90,7 @@ namespace Launcher.Gui.Screens {
void GotoNextMenu(int x, int y) {
game.Downloader.Clear();
if (File.Exists("options.txt")) {
if (Platform.FileExists("options.txt")) {
game.SetScreen(new MainScreen(game));
} else {
game.SetScreen(new ChooseModeScreen(game, true));

View File

@ -39,11 +39,11 @@ namespace Launcher.Gui.Views {
const string dateFormat = "dd-MM-yyyy HH:mm";
protected override void MakeWidgets() {
widgetIndex = 0;
string exePath = Path.Combine(Program.AppDirectory, "ClassicalSharp.exe");
DateTime writeTime = Platform.FileGetWriteTime("ClassicalSharp.exe");
Makers.Label(this, "Your build:", textFont)
.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)
.SetLocation(Anchor.Centre, Anchor.Centre, 70, -120);

View File

@ -17,28 +17,31 @@ namespace Launcher {
fontPng = false; terrainPng = false;
Options.Load();
LauncherSkin.LoadFromOptions();
if (Options.Get("nostalgia-classicbg") != null)
if (Options.Get("nostalgia-classicbg") != null) {
ClassicBackground = Options.GetBool("nostalgia-classicbg", false);
else
} else {
ClassicBackground = Options.GetBool("mode-classic", false);
}
string texDir = Path.Combine(Program.AppDirectory, "texpacks");
string texPack = Options.Get(OptionsKey.DefaultTexturePack) ?? "default.zip";
texPack = Path.Combine(texDir, texPack);
string texPath = Path.Combine("texpacks", texPack);
if (!File.Exists(texPack))
texPack = Path.Combine(texDir, "default.zip");
if (!File.Exists(texPack)) return;
if (!Platform.FileExists(texPath)) {
texPath = Path.Combine("texpacks", "default.zip");
}
if (!Platform.FileExists(texPath)) return;
ExtractTexturePack(texPack);
ExtractTexturePack(texPath);
// user selected texture pack is missing some required .png files
if (!fontPng || !terrainPng) {
texPack = Path.Combine(texDir, "default.zip");
ExtractTexturePack(texPack);
texPath = Path.Combine("texpacks", "default.zip");
ExtractTexturePack(texPath);
}
}
void ExtractTexturePack(string texPack) {
using (Stream fs = new FileStream(texPack, FileMode.Open, FileAccess.Read, FileShare.Read)) {
void ExtractTexturePack(string relPath) {
using (Stream fs = Platform.FileOpen(relPath)) {
ZipReader reader = new ZipReader();
reader.SelectZipEntry = SelectZipEntry;
reader.ProcessZipEntry = ProcessZipEntry;

View File

@ -74,6 +74,8 @@ namespace Launcher {
Window.FocusedChanged += FocusedChanged;
Window.WindowStateChanged += Resize;
Window.Keyboard.KeyDown += KeyDown;
ClassicalSharp.Program.CleanupMainDirectory();
LoadFont();
logoFont = new Font(FontName, 32, FontStyle.Regular);

View File

@ -1,6 +1,7 @@
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
using System;
using System.IO;
using ClassicalSharp;
using ClassicalSharp.Textures;
namespace Launcher.Patcher {
@ -8,21 +9,21 @@ namespace Launcher.Patcher {
public sealed class ResourceChecker {
public void CheckResourceExistence() {
string audioPath = Path.Combine(Program.AppDirectory, "audio");
if (!Directory.Exists(audioPath))
Directory.CreateDirectory(audioPath);
if (!Platform.DirectoryExists("audio")) {
Platform.DirectoryCreate("audio");
}
DigSoundsExist = CheckDigSoundsExist();
StepSoundsExist = CheckStepSoundsExist();
AllResourcesExist = DigSoundsExist && StepSoundsExist;
string texDir = Path.Combine(Program.AppDirectory, "texpacks");
string zipPath = Path.Combine(texDir, "default.zip");
bool defaultZipExists = File.Exists(zipPath);
if (File.Exists(zipPath))
CheckDefaultZip(zipPath);
string defPath = Path.Combine("texpacks", "default.zip");
if (Platform.FileExists(defPath)) {
CheckDefaultZip(defPath);
}
CheckTexturePack();
CheckMusic(audioPath);
CheckMusic();
CheckSounds();
}
@ -44,11 +45,11 @@ namespace Launcher.Patcher {
}
}
void CheckMusic(string audioPath) {
void CheckMusic() {
string[] files = ResourceList.MusicFiles;
for (int i = 0; i < files.Length; i++) {
string file = Path.Combine(audioPath, files[i]);
musicExists[i] = File.Exists(file);
string path = Path.Combine("audio", files[i]);
musicExists[i] = Platform.FileExists(path);
if (musicExists[i]) continue;
DownloadSize += musicSizes[i] / 1024f;
@ -73,14 +74,15 @@ namespace Launcher.Patcher {
public int ResourcesCount;
internal bool[] musicExists = new bool[7];
void CheckDefaultZip(string path) {
void CheckDefaultZip(string relPath) {
ZipReader reader = new ZipReader();
reader.SelectZipEntry = SelectZipEntry;
reader.ProcessZipEntry = ProcessZipEntry;
using (Stream src = new FileStream(path, FileMode.Open, FileAccess.Read))
using (Stream src = Platform.FileOpen(relPath)) {
reader.Extract(src);
}
}
bool SelectZipEntry(string filename) {
string name = ResourceList.GetFile(filename);
@ -98,20 +100,18 @@ namespace Launcher.Patcher {
bool CheckDigSoundsExist() {
string[] files = ResourceList.DigSounds;
string path = Path.Combine(Program.AppDirectory, "audio");
for (int i = 0; i < files.Length; i++) {
string file = "dig_" + files[i] + ".wav";
if (!File.Exists(Path.Combine(path, file))) return false;
string path = Path.Combine("audio", "dig_" + files[i] + ".wav");
if (!Platform.FileExists(path)) return false;
}
return true;
}
bool CheckStepSoundsExist() {
string[] files = ResourceList.StepSounds;
string path = Path.Combine(Program.AppDirectory, "audio");
for (int i = 0; i < files.Length; i++) {
string file = "step_" + files[i] + ".wav";
if (!File.Exists(Path.Combine(path, file))) return false;
string path = Path.Combine("audio", "step_" + files[i] + ".wav");
if (!Platform.FileExists(path)) return false;
}
return true;
}

View File

@ -128,9 +128,8 @@ namespace Launcher.Patcher {
return false;
if (data == null) continue;
string path = Path.Combine(Program.AppDirectory, "audio");
path = Path.Combine(path, file);
File.WriteAllBytes(path, data);
string path = Path.Combine("audio", file);
Platform.WriteAllBytes(path, data);
}
return true;
}

View File

@ -32,11 +32,16 @@ namespace Launcher.Patcher {
reader = new ZipReader();
reader.SelectZipEntry = SelectZipEntry_Classic;
reader.ProcessZipEntry = ProcessZipEntry_Classic;
string texDir = Path.Combine(Program.AppDirectory, "texpacks");
string path = Path.Combine(texDir, "default.zip");
ExtractExisting(path);
string defPath = Path.Combine("texpacks", "default.zip");
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.entries = new ZipEntry[100];
for (int i = 0; i < entries.Count; i++)
@ -60,14 +65,6 @@ namespace Launcher.Patcher {
List<ZipEntry> entries = new List<ZipEntry>();
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) {
filename = ResourceList.GetFile(filename);

View File

@ -57,10 +57,9 @@ namespace Launcher.Patcher {
}
void DecodeSound(string name, byte[] rawData) {
string path = Path.Combine(Program.AppDirectory, "audio");
path = Path.Combine(path, prefix + name + ".wav");
string path = Path.Combine("audio", prefix + name + ".wav");
using (FileStream dst = File.Create(path))
using (FileStream dst = Platform.FileCreate(path))
using (MemoryStream src = new MemoryStream(rawData))
{
dst.SetLength(44);

View File

@ -10,22 +10,20 @@ namespace Launcher {
public const string AppName = "ClassicalSharp Launcher 0.99.9.94";
public static string AppDirectory;
public static bool ShowingErrorDialog = false;
[STAThread]
static void Main(string[] args) {
AppDirectory = AppDomain.CurrentDomain.BaseDirectory;
Platform.AppDirectory = AppDomain.CurrentDomain.BaseDirectory;
string path = Path.Combine(AppDirectory, "ClassicalSharp.exe");
if (!File.Exists(path)) {
Message("ClassicalSharp.exe needs to be in the same folder as the launcher."); return;
if (!Platform.FileExists("ClassicalSharp.exe")) {
ErrorHandler.ShowDialog("Missing file", "ClassicalSharp.exe needs to be in the same folder as the launcher.");
return;
}
path = Path.Combine(AppDirectory, "OpenTK.dll");
if (!File.Exists(path)) {
Message("OpenTK.dll needs to be in the same folder as the launcher."); return;
if (!Platform.FileExists("OpenTK.dll")) {
ErrorHandler.ShowDialog("Missing file", "OpenTK.dll needs to be in the same folder as the launcher.");
return;
}
// NOTE: we purposely put this in another method, as we need to ensure
@ -34,13 +32,9 @@ namespace Launcher {
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() {
string logPath = Path.Combine(AppDirectory, "launcher.log");
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
ErrorHandler.InstallHandler(logPath);
ErrorHandler.InstallHandler("launcher.log");
OpenTK.Configuration.SkipPerfCountersHack();
LauncherWindow window = new LauncherWindow();
window.Run();

View File

@ -27,16 +27,16 @@ namespace Launcher.Updater {
ProcessStartInfo info = new ProcessStartInfo();
info.CreateNoWindow = false;
info.UseShellExecute = true;
info.WorkingDirectory = Program.AppDirectory;
info.WorkingDirectory = Platform.AppDirectory;
if (OpenTK.Configuration.RunningOnWindows) {
string path = Path.Combine(Program.AppDirectory, "update.bat");
File.WriteAllText(path, Scripts.BatchFile);
Platform.WriteAllText("update.bat", Scripts.BatchFile);
info.FileName = "cmd"; info.Arguments = "/C start cmd /C update.bat";
Process.Start(info);
} else {
string path = Path.Combine(Program.AppDirectory, "update.sh");
File.WriteAllText(path, Scripts.BashFile.Replace("\r\n", "\n"));
string path = Path.Combine(Platform.AppDirectory, "update.sh");
Platform.WriteAllText("update.sh", Scripts.BashFile.Replace("\r\n", "\n"));
const int flags = 0x7;// read | write | executable
int code = chmod(path, (flags << 6) | (flags << 3) | 4);
if (code != 0)
@ -55,23 +55,20 @@ namespace Launcher.Updater {
internal static extern int chmod(string path, int mode);
static void MakeUpdatesFolder(byte[] zipData) {
Platform.DirectoryCreate("CS_Update");
using (MemoryStream stream = new MemoryStream(zipData)) {
ZipReader reader = new ZipReader();
string path = Path.Combine(Program.AppDirectory, "CS_Update");
Directory.CreateDirectory(path);
reader.ProcessZipEntry = ProcessZipEntry;
reader.Extract(stream);
}
}
static void ProcessZipEntry(string filename, byte[] data, ZipEntry entry) {
string path = Path.Combine(Program.AppDirectory, "CS_Update");
path = Path.Combine(path, Path.GetFileName(filename));
File.WriteAllBytes(path, data);
string path = Path.Combine("CS_Update", Path.GetFileName(filename));
Platform.WriteAllBytes(path, data);
try {
File.SetLastWriteTimeUtc(path, PatchTime);
Platform.FileSetWriteTime(path, PatchTime);
} catch (IOException ex) {
ErrorHandler.LogError("I/O exception when trying to set modified time for: " + filename, ex);
} catch (UnauthorizedAccessException ex) {

View File

@ -28,15 +28,12 @@ namespace Launcher {
return StartImpl(null, true, args, ref shouldExit);
}
static bool StartImpl(ClientStartData data, bool classicubeSkins,
string args, ref bool shouldExit) {
string path = Path.Combine(Program.AppDirectory, "ClassicalSharp.exe");
if (!File.Exists(path))
return false;
static bool StartImpl(ClientStartData data, bool ccSkins, string args, ref bool shouldExit) {
if (!Platform.FileExists("ClassicalSharp.exe")) return false;
CheckSettings(data, classicubeSkins, out shouldExit);
CheckSettings(data, ccSkins, out shouldExit);
try {
StartProcess(path, args);
StartProcess(args);
} catch (Win32Exception ex) {
if ((uint)ex.ErrorCode != 0x80004005)
throw; // HRESULT when user clicks 'cancel' to 'are you sure you want to run ClassicalSharp.exe'
@ -46,7 +43,8 @@ namespace Launcher {
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) {
// We also need to handle the case of running Mono through wine
if (Configuration.RunningOnWindows) {

View File

@ -80,7 +80,7 @@ void Chat_OpenLog(DateTime* now) {
String_AppendConst(&path, ".log");
void* file;
ReturnCode code = Platform_FileOpen(&file, &path, false);
ReturnCode code = Platform_FileAppend(&file, &path);
if (code != 0 && code != ReturnCode_FileShareViolation) {
ErrorHandler_FailWithCode(code, "Chat - opening log file");
}

View File

@ -13,4 +13,5 @@ void ErrorHandler_Log(STRING_PURE String* msg);
void ErrorHandler_Fail(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); }
void ErrorHandler_ShowDialog(const UInt8* title, const UInt8* msg);
#endif

View File

@ -1275,7 +1275,7 @@ void LoadLevelScreen_EntryClick(GuiElement* screenElem, GuiElement* w) {
if (!Platform_FileExists(&path)) return;
void* file;
ReturnCode code = Platform_FileOpen(&file, &path, true);
ReturnCode code = Platform_FileOpen(&file, &path);
ErrorHandler_CheckOrFail(code, "Failed to open map file");
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);
}
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 const UInt8* descs[6] = { "Speed", "Noclip", "Half speed", "Fly", "Fly up", "Fly down" };
static ButtonWidget buttons[6];

View File

@ -141,7 +141,7 @@ void Options_Set(const UInt8* keyRaw, STRING_PURE String* value) {
void Options_Load(void) {
void* file = NULL;
String path = String_FromConst("options.txt");
ReturnCode result = Platform_FileOpen(&file, &path, true);
ReturnCode result = Platform_FileOpen(&file, &path);
if (result == ReturnCode_FileNotFound) return;
/* TODO: Should we just log failure to open? */
@ -182,7 +182,7 @@ void Options_Load(void) {
void Options_Save(void) {
void* file = NULL;
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? */
ErrorHandler_CheckOrFail(result, "Options - Saving");

View File

@ -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_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_FileWrite(void* file, UInt8* buffer, UInt32 count, UInt32* bytesWritten);
ReturnCode Platform_FileClose(void* file);

View File

@ -24,7 +24,7 @@ int main(int argc, char* argv[]) {
/*void* file;
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_FromFile(&fileStream, file, &path);
Bitmap bmp;
@ -61,7 +61,7 @@ int main(int argc, char* argv[]) {
/*void* file;
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_FromFile(&fileStream, file, &path);
ZipState state;
@ -71,7 +71,7 @@ int main(int argc, char* argv[]) {
void* file;
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_FromFile(&fileStream, file, &path);
Lvl_Load(&fileStream);
@ -79,7 +79,7 @@ int main(int argc, char* argv[]) {
/*void* file;
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_FromFile(&fileStream, file, &path);

View File

@ -32,8 +32,7 @@ void ErrorHandler_Fail(const UInt8* raw_msg) {
ErrorHandler_WriteLogBody(raw_msg);
ErrorHandler_WriteLogEnd();
HWND win = GetActiveWindow();
MessageBoxA(win, logMsg.buffer, "We're sorry", 0);
ErrorHandler_ShowDialog("We're sorry", logMsg.buffer);
ExitProcess(1);
}
@ -45,7 +44,11 @@ void ErrorHandler_FailWithCode(ReturnCode code, const UInt8* raw_msg) {
String_AppendConst(&logMsg, "\r\n");
ErrorHandler_WriteLogEnd();
HWND win = GetActiveWindow(); /* TODO: It's probably wrong to use GetActiveWindow() here */
MessageBoxA(win, logMsg.buffer, "We're sorry", 0);
ErrorHandler_ShowDialog("We're sorry", logMsg.buffer);
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);
}

View File

@ -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) {
UINT32 access = GENERIC_READ;
if (!readOnly) access |= GENERIC_WRITE;
HANDLE handle = CreateFileA(path->buffer, access, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
ReturnCode Platform_FileOpen(void** file, STRING_PURE String* path) {
HANDLE handle = CreateFileA(path->buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
*file = (void*)handle;
return handle != INVALID_HANDLE_VALUE ? 0 : GetLastError();
}
ReturnCode Platform_FileCreate(void** file, STRING_PURE String* path) {
UINT32 access = GENERIC_READ | GENERIC_WRITE;
HANDLE handle = CreateFileA(path->buffer, access, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE handle = CreateFileA(path->buffer, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
*file = (void*)handle;
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) {
BOOL success = ReadFile((HANDLE)file, buffer, count, bytesRead, NULL);
return success ? 0 : GetLastError();
@ -187,11 +192,11 @@ ReturnCode Platform_FileSeek(void* file, Int32 offset, Int32 seekType) {
DWORD pos;
switch (seekType) {
case STREAM_SEEKFROM_BEGIN:
pos = SetFilePointer(file, offset, NULL, 0); break;
pos = SetFilePointer(file, offset, NULL, FILE_BEGIN); break;
case STREAM_SEEKFROM_CURRENT:
pos = SetFilePointer(file, offset, NULL, 1); break;
pos = SetFilePointer(file, offset, NULL, FILE_CURRENT); break;
case STREAM_SEEKFROM_END:
pos = SetFilePointer(file, offset, NULL, 2); break;
pos = SetFilePointer(file, offset, NULL, FILE_END); break;
default:
ErrorHandler_Fail("Invalid SeekType provided when seeking file");
}