Index: ps/trunk/binaries/data/mods/public/gui/replaymenu/replay_actions.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/replaymenu/replay_actions.js +++ ps/trunk/binaries/data/mods/public/gui/replaymenu/replay_actions.js @@ -189,7 +189,7 @@ var selectedIndex = replaySelection.selected; if (!Engine.DeleteReplay(replayDirectory)) - error(sprintf("Could not delete replay '%(id)s'", { "id": replayDirectory })); + error("Could not delete replay!"); // Refresh replay list init(); Index: ps/trunk/source/gui/scripting/ScriptFunctions.cpp =================================================================== --- ps/trunk/source/gui/scripting/ScriptFunctions.cpp +++ ps/trunk/source/gui/scripting/ScriptFunctions.cpp @@ -211,7 +211,7 @@ return std::wstring(); if (g_Game->IsVisualReplay()) - return OsPath(g_Game->GetReplayPath()).Parent().Filename().string(); + return g_Game->GetReplayPath().Parent().Filename().string(); return g_Game->GetReplayLogger().GetDirectory().Filename().string(); } Index: ps/trunk/source/main.cpp =================================================================== --- ps/trunk/source/main.cpp +++ ps/trunk/source/main.cpp @@ -467,20 +467,20 @@ const bool isNonVisualReplay = args.Has("replay"); const bool isNonVisual = args.Has("autostart-nonvisual"); - const CStr replayFile = + const OsPath replayFile( isVisualReplay ? args.Get("replay-visual") : - isNonVisualReplay ? args.Get("replay") : ""; + isNonVisualReplay ? args.Get("replay") : ""); if (isVisualReplay || isNonVisualReplay) { - if (!FileExists(OsPath(replayFile))) + if (!FileExists(replayFile)) { - debug_printf("ERROR: The requested replay file '%s' does not exist!\n", replayFile.c_str()); + debug_printf("ERROR: The requested replay file '%s' does not exist!\n", replayFile.string8().c_str()); return; } - if (DirectoryExists(OsPath(replayFile))) + if (DirectoryExists(replayFile)) { - debug_printf("ERROR: The requested replay file '%s' is a directory!\n", replayFile.c_str()); + debug_printf("ERROR: The requested replay file '%s' is a directory!\n", replayFile.string8().c_str()); return; } } Index: ps/trunk/source/network/NetClientTurnManager.cpp =================================================================== --- ps/trunk/source/network/NetClientTurnManager.cpp +++ ps/trunk/source/network/NetClientTurnManager.cpp @@ -143,7 +143,7 @@ scriptInterface.SetProperty(msg, "players", playerNamesStrings); scriptInterface.SetProperty(msg, "expectedHash", expectedHashHex); scriptInterface.SetProperty(msg, "hash", Hexify(hash)); - scriptInterface.SetProperty(msg, "path_oos_dump", path.string8()); - scriptInterface.SetProperty(msg, "path_replay", m_Replay.GetDirectory().string8()); + scriptInterface.SetProperty(msg, "path_oos_dump", wstring_from_utf8(path.string8())); + scriptInterface.SetProperty(msg, "path_replay", wstring_from_utf8(m_Replay.GetDirectory().string8())); m_NetClient.PushGuiMessage(msg); } Index: ps/trunk/source/ps/Game.h =================================================================== --- ps/trunk/source/ps/Game.h +++ ps/trunk/source/ps/Game.h @@ -18,9 +18,10 @@ #ifndef INCLUDED_GAME #define INCLUDED_GAME -#include "ps/Errors.h" #include +#include "ps/Errors.h" +#include "ps/Filesystem.h" #include "scriptinterface/ScriptVal.h" #include "simulation2/helpers/Player.h" @@ -91,7 +92,7 @@ void StartGame(JS::MutableHandleValue attribs, const std::string& savedState); PSRETURN ReallyStartGame(); - bool StartVisualReplay(const std::string& replayPath); + bool StartVisualReplay(const OsPath& replayPath); /** * Periodic heartbeat that controls the process. performs all per-frame updates. @@ -196,7 +197,7 @@ inline float GetSimRate() const { return m_SimRate; } - inline std::string GetReplayPath() const + inline OsPath GetReplayPath() const { return m_ReplayPath; } /** @@ -222,7 +223,7 @@ bool m_IsSavedGame; // true if loading a saved game; false for a new game int LoadVisualReplayData(); - std::string m_ReplayPath; + OsPath m_ReplayPath; bool m_IsVisualReplay; std::istream* m_ReplayStream; u32 m_FinalReplayTurn; Index: ps/trunk/source/ps/Game.cpp =================================================================== --- ps/trunk/source/ps/Game.cpp +++ ps/trunk/source/ps/Game.cpp @@ -168,9 +168,9 @@ return 0; } -bool CGame::StartVisualReplay(const std::string& replayPath) +bool CGame::StartVisualReplay(const OsPath& replayPath) { - debug_printf("Starting to replay %s\n", replayPath.c_str()); + debug_printf("Starting to replay %s\n", replayPath.string8().c_str()); m_IsVisualReplay = true; ScriptInterface& scriptInterface = m_Simulation2->GetScriptInterface(); @@ -178,7 +178,7 @@ SetTurnManager(new CReplayTurnManager(*m_Simulation2, GetReplayLogger())); m_ReplayPath = replayPath; - m_ReplayStream = new std::ifstream(m_ReplayPath.c_str()); + m_ReplayStream = new std::ifstream(OsString(replayPath).c_str()); std::string type; ENSURE((*m_ReplayStream >> type).good() && type == "start"); Index: ps/trunk/source/ps/Replay.h =================================================================== --- ps/trunk/source/ps/Replay.h +++ ps/trunk/source/ps/Replay.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -96,7 +96,7 @@ CReplayPlayer(); ~CReplayPlayer(); - void Load(const std::string& path); + void Load(const OsPath& path); void Replay(bool serializationtest, int rejointestturn, bool ooslog); private: Index: ps/trunk/source/ps/Replay.cpp =================================================================== --- ps/trunk/source/ps/Replay.cpp +++ ps/trunk/source/ps/Replay.cpp @@ -106,11 +106,11 @@ delete m_Stream; } -void CReplayPlayer::Load(const std::string& path) +void CReplayPlayer::Load(const OsPath& path) { ENSURE(!m_Stream); - m_Stream = new std::ifstream(path.c_str()); + m_Stream = new std::ifstream(OsString(path).c_str()); ENSURE(m_Stream->good()); } Index: ps/trunk/source/ps/VisualReplay.h =================================================================== --- ps/trunk/source/ps/VisualReplay.h +++ ps/trunk/source/ps/VisualReplay.h @@ -39,7 +39,7 @@ /** * Replays the commands.txt file in the given subdirectory visually. */ -void StartVisualReplay(const CStrW& directory); +void StartVisualReplay(const OsPath& directory); /** * Reads the replay Cache file and parses it into a jsObject @@ -89,22 +89,22 @@ * @param replayFile - path to commands.txt, whose parent directory will be deleted. * @return true if deletion was successful, false on error */ -bool DeleteReplay(const CStrW& replayFile); +bool DeleteReplay(const OsPath& replayFile); /** * Returns the parsed header of the replay file (commands.txt). */ -JS::Value GetReplayAttributes(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& directoryName); +JS::Value GetReplayAttributes(ScriptInterface::CxPrivate* pCxPrivate, const OsPath& directoryName); /** * Returns whether or not the metadata / summary screen data has been saved properly when the game ended. */ -bool HasReplayMetadata(const CStrW& directoryName); +bool HasReplayMetadata(const OsPath& directoryName); /** * Returns the metadata of a replay. */ -JS::Value GetReplayMetadata(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& directoryName); +JS::Value GetReplayMetadata(ScriptInterface::CxPrivate* pCxPrivate, const OsPath& directoryName); /** * Saves the metadata from the session to metadata.json. Index: ps/trunk/source/ps/VisualReplay.cpp =================================================================== --- ps/trunk/source/ps/VisualReplay.cpp +++ ps/trunk/source/ps/VisualReplay.cpp @@ -49,7 +49,7 @@ return OsPath(paths.UserData() / "replays" / engine_version); } -void VisualReplay::StartVisualReplay(const CStrW& directory) +void VisualReplay::StartVisualReplay(const OsPath& directory) { ENSURE(!g_NetServer); ENSURE(!g_NetClient); @@ -61,7 +61,7 @@ return; g_Game = new CGame(false, false); - g_Game->StartVisualReplay(replayFile.string8()); + g_Game->StartVisualReplay(replayFile); } bool VisualReplay::ReadCacheFile(ScriptInterface& scriptInterface, JS::MutableHandleObject cachedReplaysObject) @@ -72,7 +72,7 @@ if (!FileExists(cacheFileName)) return false; - std::ifstream cacheStream(cacheFileName.string8().c_str()); + std::ifstream cacheStream(OsString(cacheFileName).c_str()); CStr cacheStr((std::istreambuf_iterator(cacheStream)), std::istreambuf_iterator()); cacheStream.close(); @@ -95,7 +95,7 @@ JSAutoRequest rq(cx); JS::RootedValue replaysRooted(cx, JS::ObjectValue(*replays)); - std::ofstream cacheStream(tempCacheFileName.string8().c_str(), std::ofstream::out | std::ofstream::trunc); + std::ofstream cacheStream(OsString(tempCacheFileName).c_str(), std::ofstream::out | std::ofstream::trunc); cacheStream << scriptInterface.StringifyJSON(&replaysRooted); cacheStream.close(); @@ -111,7 +111,7 @@ JSAutoRequest rq(cx); // Maps the filename onto the index and size - typedef std::map> replayCacheMap; + typedef std::map> replayCacheMap; replayCacheMap fileList; @@ -127,7 +127,7 @@ JS_GetElement(cx, cachedReplaysObject, j, &replay); JS::RootedValue file(cx); - CStr fileName; + OsPath fileName; double fileSize; scriptInterface.GetProperty(replay, "directory", fileName); scriptInterface.GetProperty(replay, "fileSize", fileSize); @@ -158,7 +158,7 @@ continue; bool isNew = true; - replayCacheMap::iterator it = fileList.find(directory.string8()); + replayCacheMap::iterator it = fileList.find(directory); if (it != fileList.end()) { if (compareFiles) @@ -180,7 +180,7 @@ CFileInfo fileInfo; GetFileInfo(replayFile, &fileInfo); scriptInterface.Eval("({})", &replayData); - scriptInterface.SetProperty(replayData, "directory", directory); + scriptInterface.SetProperty(replayData, "directory", directory.string()); scriptInterface.SetProperty(replayData, "fileSize", (double)fileInfo.Size()); } JS_SetElement(cx, replays, i++, replayData); @@ -241,7 +241,7 @@ * * @return The current cursor position or -1 on error. */ -inline int goBackToLineBeginning(std::istream* replayStream, const CStr& fileName, const u64& fileSize) +inline off_t goBackToLineBeginning(std::istream* replayStream, const OsPath& fileName, off_t fileSize) { int currentPos; char character; @@ -255,7 +255,7 @@ if (!replayStream->good()) { - LOGERROR("Unknown error when returning to the last line (%i of %lu) of %s", currentPos, fileSize, fileName.c_str()); + LOGERROR("Unknown error when returning to the last line (%i of %lu) of %s", currentPos, fileSize, fileName.string8().c_str()); return -1; } @@ -269,7 +269,7 @@ replayStream->seekg(-2, std::ios_base::cur); } - LOGERROR("Infinite loop when going back to a line beginning in %s", fileName.c_str()); + LOGERROR("Infinite loop when going back to a line beginning in %s", fileName.string8().c_str()); return -1; } @@ -279,7 +279,7 @@ * * @return seconds or -1 on error */ -inline int getReplayDuration(std::istream* replayStream, const CStr& fileName, const u64& fileSize) +inline int getReplayDuration(std::istream* replayStream, const OsPath& fileName, off_t fileSize) { CStr type; @@ -290,7 +290,7 @@ // There should be about 5 lines to read until a turn is found. for (int linesRead = 1; linesRead < 1000; ++linesRead) { - int currentPosition = goBackToLineBeginning(replayStream, fileName, fileSize); + off_t currentPosition = goBackToLineBeginning(replayStream, fileName, fileSize); // Read error or reached file beginning. No turns exist. if (currentPosition < 1) @@ -298,12 +298,12 @@ if (!replayStream->good()) { - LOGERROR("Read error when determining replay duration at %i of %llu in %s", currentPosition - 2, fileSize, fileName.c_str()); + LOGERROR("Read error when determining replay duration at %i of %llu in %s", currentPosition - 2, fileSize, fileName.string8().c_str()); return -1; } // Found last turn, compute duration. - if ((u64) currentPosition + 4 < fileSize && (*replayStream >> type).good() && type == "turn") + if (currentPosition + 4 < fileSize && (*replayStream >> type).good() && type == "turn") { u32 turn = 0, turnLength = 0; *replayStream >> turn >> turnLength; @@ -314,7 +314,7 @@ replayStream->seekg(currentPosition - 2, std::ios_base::beg); } - LOGERROR("Infinite loop when determining replay duration for %s", fileName.c_str()); + LOGERROR("Infinite loop when determining replay duration for %s", fileName.string8().c_str()); return -1; } @@ -329,26 +329,24 @@ // Get file size and modification date CFileInfo fileInfo; GetFileInfo(replayFile, &fileInfo); - const u64 fileSize = (u64)fileInfo.Size(); + const off_t fileSize = fileInfo.Size(); if (fileSize == 0) return JSVAL_NULL; - // Open file - const CStr fileName = replayFile.string8(); - std::ifstream* replayStream = new std::ifstream(fileName.c_str()); + std::ifstream* replayStream = new std::ifstream(OsString(replayFile).c_str()); - // File must begin with "start" CStr type; if (!(*replayStream >> type).good()) { - LOGERROR("Couldn't open %s. Non-latin characters are not supported yet.", fileName.c_str()); + LOGERROR("Couldn't open %s.", replayFile.string8().c_str()); SAFE_DELETE(replayStream); return JSVAL_NULL; } + if (type != "start") { - LOGWARNING("The replay %s is broken!", fileName.c_str()); + LOGWARNING("The replay %s doesn't begin with 'start'!", replayFile.string8().c_str()); SAFE_DELETE(replayStream); return JSVAL_NULL; } @@ -361,7 +359,7 @@ JS::RootedValue attribs(cx); if (!scriptInterface.ParseJSON(header, &attribs)) { - LOGERROR("Couldn't parse replay header of %s", fileName.c_str()); + LOGERROR("Couldn't parse replay header of %s", replayFile.string8().c_str()); SAFE_DELETE(replayStream); return JSVAL_NULL; } @@ -382,7 +380,7 @@ return JSVAL_NULL; } - int duration = getReplayDuration(replayStream, fileName, fileSize); + int duration = getReplayDuration(replayStream, replayFile, fileSize); SAFE_DELETE(replayStream); @@ -393,14 +391,14 @@ // Return the actual data JS::RootedValue replayData(cx); scriptInterface.Eval("({})", &replayData); - scriptInterface.SetProperty(replayData, "directory", directory); + scriptInterface.SetProperty(replayData, "directory", directory.string()); scriptInterface.SetProperty(replayData, "fileSize", (double)fileSize); scriptInterface.SetProperty(replayData, "attribs", attribs); scriptInterface.SetProperty(replayData, "duration", duration); return replayData; } -bool VisualReplay::DeleteReplay(const CStrW& replayDirectory) +bool VisualReplay::DeleteReplay(const OsPath& replayDirectory) { if (replayDirectory.empty()) return false; @@ -409,7 +407,7 @@ return DirectoryExists(directory) && DeleteDirectory(directory) == INFO::OK; } -JS::Value VisualReplay::GetReplayAttributes(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& directoryName) +JS::Value VisualReplay::GetReplayAttributes(ScriptInterface::CxPrivate* pCxPrivate, const OsPath& directoryName) { // Create empty JS object JSContext* cx = pCxPrivate->pScriptInterface->GetContext(); @@ -423,7 +421,7 @@ return attribs; // Open file - std::istream* replayStream = new std::ifstream(replayFile.string8().c_str()); + std::istream* replayStream = new std::ifstream(OsString(replayFile).c_str()); CStr type, line; ENSURE((*replayStream >> type).good() && type == "start"); @@ -473,13 +471,13 @@ const OsPath fileName = g_Game->GetReplayLogger().GetDirectory() / L"metadata.json"; CreateDirectories(fileName.Parent(), 0700); - std::ofstream stream (fileName.string8().c_str(), std::ofstream::out | std::ofstream::trunc); + std::ofstream stream (OsString(fileName).c_str(), std::ofstream::out | std::ofstream::trunc); stream << scriptInterface->StringifyJSON(&metadata, false); stream.close(); debug_printf("Saved replay metadata to %s\n", fileName.string8().c_str()); } -bool VisualReplay::HasReplayMetadata(const CStrW& directoryName) +bool VisualReplay::HasReplayMetadata(const OsPath& directoryName) { const OsPath filePath(GetDirectoryName() / directoryName / L"metadata.json"); @@ -492,7 +490,7 @@ return fileInfo.Size() > 0; } -JS::Value VisualReplay::GetReplayMetadata(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& directoryName) +JS::Value VisualReplay::GetReplayMetadata(ScriptInterface::CxPrivate* pCxPrivate, const OsPath& directoryName) { if (!HasReplayMetadata(directoryName)) return JSVAL_NULL; @@ -501,7 +499,7 @@ JSAutoRequest rq(cx); JS::RootedValue metadata(cx); - std::ifstream* stream = new std::ifstream(OsPath(GetDirectoryName() / directoryName / L"metadata.json").string8()); + std::ifstream* stream = new std::ifstream(OsString(GetDirectoryName() / directoryName / L"metadata.json").c_str()); ENSURE(stream->good()); CStr line; std::getline(*stream, line); Index: ps/trunk/source/ps/scripting/JSInterface_VisualReplay.cpp =================================================================== --- ps/trunk/source/ps/scripting/JSInterface_VisualReplay.cpp +++ ps/trunk/source/ps/scripting/JSInterface_VisualReplay.cpp @@ -60,7 +60,7 @@ CStrW JSI_VisualReplay::GetReplayDirectoryName(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const CStrW& directoryName) { - return OsPath(VisualReplay::GetDirectoryName() / directoryName).string(); + return wstring_from_utf8(OsPath(VisualReplay::GetDirectoryName() / directoryName).string8()); } void JSI_VisualReplay::RegisterScriptFunctions(ScriptInterface& scriptInterface)