mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-31 15:32:42 +00:00
user-manager: squash all commits for this feature.
This commit is contained in:
parent
c5c0f68b3e
commit
948bd3673e
@ -4,6 +4,7 @@
|
||||
#include "utils.h"
|
||||
#include "unself.h"
|
||||
#include "Emu/VFS.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <zlib.h>
|
||||
@ -1294,7 +1295,7 @@ bool SELFDecrypter::GetKeyFromRap(u8* content_id, u8* npdrm_key)
|
||||
|
||||
// Try to find a matching RAP file under exdata folder.
|
||||
const std::string ci_str = reinterpret_cast<const char*>(content_id);
|
||||
const std::string rap_path = "/dev_hdd0/home/00000001/exdata/" + ci_str + ".rap";
|
||||
const std::string rap_path = fmt::format("/dev_hdd0/home/%s/exdata/%s.rap", Emu.GetUsr(), ci_str);
|
||||
|
||||
// Open the RAP file and read the key.
|
||||
const fs::file rap_file(vfs::get(rap_path));
|
||||
|
@ -85,8 +85,8 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
vm::ptr<CellSaveDataFileSet> fileSet = g_savedata_context.ptr(&savedata_context::fileSet);
|
||||
vm::ptr<CellSaveDataDoneGet> doneGet = g_savedata_context.ptr(&savedata_context::doneGet);
|
||||
|
||||
//TODO: get current user ID
|
||||
// userId(0) = CELL_SYSUTIL_USERID_CURRENT
|
||||
// TODO: now that we have Emu.GetUsrId(), do we need "userId ? userId : 1u"? Replace with error check?
|
||||
// userId(0) = CELL_SYSUTIL_USERID_CURRENT;
|
||||
// path of the specified user (00000001 by default)
|
||||
const std::string base_dir = vfs::get(fmt::format("/dev_hdd0/home/%08u/savedata/", userId ? userId : 1u));
|
||||
|
||||
@ -843,10 +843,9 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
|
||||
static NEVER_INLINE s32 savedata_get_list_item(vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB, u32 userId)
|
||||
{
|
||||
//TODO: accurately get the current user
|
||||
if (userId == 0)
|
||||
{
|
||||
userId = 1u;
|
||||
userId = Emu.GetUsrId();
|
||||
}
|
||||
std::string save_path = vfs::get(fmt::format("/dev_hdd0/home/%08u/savedata/%s/", userId, dirName.get_ptr()));
|
||||
std::string sfo = save_path + "PARAM.SFO";
|
||||
@ -910,7 +909,7 @@ s32 cellSaveDataListSave2(ppu_thread& ppu, u32 version, PSetList setList, PSetBu
|
||||
cellSaveData.warning("cellSaveDataListSave2(version=%d, setList=*0x%x, setBuf=*0x%x, funcList=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)",
|
||||
version, setList, setBuf, funcList, funcStat, funcFile, container, userdata);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_SAVE, version, vm::null, 1, setList, setBuf, funcList, vm::null, funcStat, funcFile, container, 2, userdata, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_SAVE, version, vm::null, 1, setList, setBuf, funcList, vm::null, funcStat, funcFile, container, 2, userdata, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataListLoad2(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncList funcList,
|
||||
@ -919,7 +918,7 @@ s32 cellSaveDataListLoad2(ppu_thread& ppu, u32 version, PSetList setList, PSetBu
|
||||
cellSaveData.warning("cellSaveDataListLoad2(version=%d, setList=*0x%x, setBuf=*0x%x, funcList=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)",
|
||||
version, setList, setBuf, funcList, funcStat, funcFile, container, userdata);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_LOAD, version, vm::null, 1, setList, setBuf, funcList, vm::null, funcStat, funcFile, container, 2, userdata, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_LOAD, version, vm::null, 1, setList, setBuf, funcList, vm::null, funcStat, funcFile, container, 2, userdata, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataListSave(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncList funcList,
|
||||
@ -928,7 +927,7 @@ s32 cellSaveDataListSave(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf
|
||||
cellSaveData.warning("cellSaveDataListSave(version=%d, setList=*0x%x, setBuf=*0x%x, funcList=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x)",
|
||||
version, setList, setBuf, funcList, funcStat, funcFile, container);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_SAVE, version, vm::null, 1, setList, setBuf, funcList, vm::null, funcStat, funcFile, container, 2, vm::null, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_SAVE, version, vm::null, 1, setList, setBuf, funcList, vm::null, funcStat, funcFile, container, 2, vm::null, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataListLoad(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncList funcList,
|
||||
@ -937,7 +936,7 @@ s32 cellSaveDataListLoad(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf
|
||||
cellSaveData.warning("cellSaveDataListLoad(version=%d, setList=*0x%x, setBuf=*0x%x, funcList=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x)",
|
||||
version, setList, setBuf, funcList, funcStat, funcFile, container);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_LOAD, version, vm::null, 1, setList, setBuf, funcList, vm::null, funcStat, funcFile, container, 2, vm::null, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_LOAD, version, vm::null, 1, setList, setBuf, funcList, vm::null, funcStat, funcFile, container, 2, vm::null, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataFixedSave2(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncFixed funcFixed,
|
||||
@ -946,7 +945,7 @@ s32 cellSaveDataFixedSave2(ppu_thread& ppu, u32 version, PSetList setList, PSetB
|
||||
cellSaveData.warning("cellSaveDataFixedSave2(version=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)",
|
||||
version, setList, setBuf, funcFixed, funcStat, funcFile, container, userdata);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_FIXED_SAVE, version, vm::null, 1, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 2, userdata, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_FIXED_SAVE, version, vm::null, 1, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 2, userdata, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataFixedLoad2(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncFixed funcFixed,
|
||||
@ -955,7 +954,7 @@ s32 cellSaveDataFixedLoad2(ppu_thread& ppu, u32 version, PSetList setList, PSetB
|
||||
cellSaveData.warning("cellSaveDataFixedLoad2(version=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)",
|
||||
version, setList, setBuf, funcFixed, funcStat, funcFile, container, userdata);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_FIXED_LOAD, version, vm::null, 1, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 2, userdata, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_FIXED_LOAD, version, vm::null, 1, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 2, userdata, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataFixedSave(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncFixed funcFixed,
|
||||
@ -964,7 +963,7 @@ s32 cellSaveDataFixedSave(ppu_thread& ppu, u32 version, PSetList setList, PSetBu
|
||||
cellSaveData.warning("cellSaveDataFixedSave(version=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x)",
|
||||
version, setList, setBuf, funcFixed, funcStat, funcFile, container);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_FIXED_SAVE, version, vm::null, 1, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 2, vm::null, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_FIXED_SAVE, version, vm::null, 1, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 2, vm::null, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataFixedLoad(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncFixed funcFixed,
|
||||
@ -973,7 +972,7 @@ s32 cellSaveDataFixedLoad(ppu_thread& ppu, u32 version, PSetList setList, PSetBu
|
||||
cellSaveData.warning("cellSaveDataFixedLoad(version=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x)",
|
||||
version, setList, setBuf, funcFixed, funcStat, funcFile, container);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_FIXED_LOAD, version, vm::null, 1, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 2, vm::null, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_FIXED_LOAD, version, vm::null, 1, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 2, vm::null, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataAutoSave2(ppu_thread& ppu, u32 version, vm::cptr<char> dirName, u32 errDialog, PSetBuf setBuf,
|
||||
@ -982,7 +981,7 @@ s32 cellSaveDataAutoSave2(ppu_thread& ppu, u32 version, vm::cptr<char> dirName,
|
||||
cellSaveData.warning("cellSaveDataAutoSave2(version=%d, dirName=%s, errDialog=%d, setBuf=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)",
|
||||
version, dirName, errDialog, setBuf, funcStat, funcFile, container, userdata);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_AUTO_SAVE, version, dirName, errDialog, vm::null, setBuf, vm::null, vm::null, funcStat, funcFile, container, 2, userdata, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_AUTO_SAVE, version, dirName, errDialog, vm::null, setBuf, vm::null, vm::null, funcStat, funcFile, container, 2, userdata, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataAutoLoad2(ppu_thread& ppu, u32 version, vm::cptr<char> dirName, u32 errDialog, PSetBuf setBuf,
|
||||
@ -991,7 +990,7 @@ s32 cellSaveDataAutoLoad2(ppu_thread& ppu, u32 version, vm::cptr<char> dirName,
|
||||
cellSaveData.warning("cellSaveDataAutoLoad2(version=%d, dirName=%s, errDialog=%d, setBuf=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)",
|
||||
version, dirName, errDialog, setBuf, funcStat, funcFile, container, userdata);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_AUTO_LOAD, version, dirName, errDialog, vm::null, setBuf, vm::null, vm::null, funcStat, funcFile, container, 2, userdata, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_AUTO_LOAD, version, dirName, errDialog, vm::null, setBuf, vm::null, vm::null, funcStat, funcFile, container, 2, userdata, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataAutoSave(ppu_thread& ppu, u32 version, vm::cptr<char> dirName, u32 errDialog, PSetBuf setBuf,
|
||||
@ -1000,7 +999,7 @@ s32 cellSaveDataAutoSave(ppu_thread& ppu, u32 version, vm::cptr<char> dirName, u
|
||||
cellSaveData.warning("cellSaveDataAutoSave(version=%d, dirName=%s, errDialog=%d, setBuf=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x)",
|
||||
version, dirName, errDialog, setBuf, funcStat, funcFile, container);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_AUTO_SAVE, version, dirName, errDialog, vm::null, setBuf, vm::null, vm::null, funcStat, funcFile, container, 2, vm::null, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_AUTO_SAVE, version, dirName, errDialog, vm::null, setBuf, vm::null, vm::null, funcStat, funcFile, container, 2, vm::null, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataAutoLoad(ppu_thread& ppu, u32 version, vm::cptr<char> dirName, u32 errDialog, PSetBuf setBuf,
|
||||
@ -1009,7 +1008,7 @@ s32 cellSaveDataAutoLoad(ppu_thread& ppu, u32 version, vm::cptr<char> dirName, u
|
||||
cellSaveData.warning("cellSaveDataAutoLoad(version=%d, dirName=%s, errDialog=%d, setBuf=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x)",
|
||||
version, dirName, errDialog, setBuf, funcStat, funcFile, container);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_AUTO_LOAD, version, dirName, errDialog, vm::null, setBuf, vm::null, vm::null, funcStat, funcFile, container, 2, vm::null, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_AUTO_LOAD, version, dirName, errDialog, vm::null, setBuf, vm::null, vm::null, funcStat, funcFile, container, 2, vm::null, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataListAutoSave(ppu_thread& ppu, u32 version, u32 errDialog, PSetList setList, PSetBuf setBuf, PFuncFixed funcFixed, PFuncStat funcStat, PFuncFile funcFile, u32 container, vm::ptr<void> userdata)
|
||||
@ -1017,7 +1016,7 @@ s32 cellSaveDataListAutoSave(ppu_thread& ppu, u32 version, u32 errDialog, PSetLi
|
||||
cellSaveData.warning("cellSaveDataListAutoSave(version=%d, errDialog=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)",
|
||||
version, errDialog, setList, setBuf, funcFixed, funcStat, funcFile, container, userdata);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_AUTO_SAVE, version, vm::null, errDialog, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 0, userdata, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_AUTO_SAVE, version, vm::null, errDialog, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 0, userdata, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataListAutoLoad(ppu_thread& ppu, u32 version, u32 errDialog, PSetList setList, PSetBuf setBuf, PFuncFixed funcFixed, PFuncStat funcStat, PFuncFile funcFile, u32 container, vm::ptr<void> userdata)
|
||||
@ -1025,7 +1024,7 @@ s32 cellSaveDataListAutoLoad(ppu_thread& ppu, u32 version, u32 errDialog, PSetLi
|
||||
cellSaveData.warning("cellSaveDataListAutoLoad(version=%d, errDialog=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)",
|
||||
version, errDialog, setList, setBuf, funcFixed, funcStat, funcFile, container, userdata);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_AUTO_LOAD, version, vm::null, errDialog, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 0, userdata, 0, vm::null);
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_AUTO_LOAD, version, vm::null, errDialog, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 0, userdata, Emu.GetUsrId(), vm::null);
|
||||
}
|
||||
|
||||
s32 cellSaveDataDelete2(u32 container)
|
||||
@ -1047,7 +1046,7 @@ s32 cellSaveDataFixedDelete(ppu_thread& ppu, PSetList setList, PSetBuf setBuf, P
|
||||
cellSaveData.warning("cellSaveDataFixedDelete(setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcDone=*0x%x, container=0x%x, userdata=*0x%x)",
|
||||
setList, setBuf, funcFixed, funcDone, container, userdata);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_FIXED_DELETE, 0, vm::null, 1, setList, setBuf, vm::null, funcFixed, vm::null, vm::null, container, 2, userdata, 0, funcDone);
|
||||
return savedata_op(ppu, SAVEDATA_OP_FIXED_DELETE, 0, vm::null, 1, setList, setBuf, vm::null, funcFixed, vm::null, vm::null, container, 2, userdata, Emu.GetUsrId(), funcDone);
|
||||
}
|
||||
|
||||
s32 cellSaveDataUserListSave(ppu_thread& ppu, u32 version, u32 userId, PSetList setList, PSetBuf setBuf, PFuncList funcList, PFuncStat funcStat, PFuncFile funcFile, u32 container, vm::ptr<void> userdata)
|
||||
@ -1133,7 +1132,7 @@ s32 cellSaveDataListDelete(ppu_thread& ppu, PSetList setList, PSetBuf setBuf, PF
|
||||
{
|
||||
cellSaveData.warning("cellSaveDataListDelete(setList=*0x%x, setBuf=*0x%x, funcList=*0x%x, funcDone=*0x%x, container=0x%x, userdata=*0x%x)", setList, setBuf, funcList, funcDone, container, userdata);
|
||||
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_DELETE, 0, vm::null, 0, setList, setBuf, funcList, vm::null, vm::null, vm::null, container, 0x40, userdata, 0, funcDone);
|
||||
return savedata_op(ppu, SAVEDATA_OP_LIST_DELETE, 0, vm::null, 0, setList, setBuf, funcList, vm::null, vm::null, vm::null, container, 0x40, userdata, Emu.GetUsrId(), funcDone);
|
||||
}
|
||||
|
||||
s32 cellSaveDataListImport(ppu_thread& ppu, PSetList setList, u32 maxSizeKB, PFuncDone funcDone, u32 container, vm::ptr<void> userdata)
|
||||
@ -1166,7 +1165,7 @@ s32 cellSaveDataFixedExport(ppu_thread& ppu, vm::cptr<char> dirName, u32 maxSize
|
||||
|
||||
s32 cellSaveDataGetListItem(vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB)
|
||||
{
|
||||
cellSaveData.warning("cellSavaDataGetListItem(dirName=%s, dir=*0x%x, sysFileParam=*0x%x, bind=*0x%x, sizeKB=*0x%x)", dirName, dir, sysFileParam, bind, sizeKB);
|
||||
cellSaveData.warning("cellSaveDataGetListItem(dirName=%s, dir=*0x%x, sysFileParam=*0x%x, bind=*0x%x, sizeKB=*0x%x)", dirName, dir, sysFileParam, bind, sizeKB);
|
||||
|
||||
return savedata_get_list_item(dirName, dir, sysFileParam, bind, sizeKB, 0);
|
||||
}
|
||||
@ -1208,7 +1207,7 @@ s32 cellSaveDataUserFixedExport(ppu_thread& ppu, u32 userId, vm::cptr<char> dirN
|
||||
|
||||
s32 cellSaveDataUserGetListItem(u32 userId, vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB)
|
||||
{
|
||||
cellSaveData.warning("cellSavaDataGetListItem(dirName=%s, dir=*0x%x, sysFileParam=*0x%x, bind=*0x%x, sizeKB=*0x%x, userID=*0x%x)", dirName, dir, sysFileParam, bind, sizeKB, userId);
|
||||
cellSaveData.warning("cellSaveDataGetListItem(dirName=%s, dir=*0x%x, sysFileParam=*0x%x, bind=*0x%x, sizeKB=*0x%x, userID=*0x%x)", dirName, dir, sysFileParam, bind, sizeKB, userId);
|
||||
|
||||
return savedata_get_list_item(dirName, dir, sysFileParam, bind, sizeKB, userId);
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ error_code cellUserInfoGetStat(u32 id, vm::ptr<CellUserInfoUserStat> stat)
|
||||
|
||||
if (id == CELL_SYSUTIL_USERID_CURRENT)
|
||||
{
|
||||
// TODO: Return current user/profile when that is implemented
|
||||
id = 1;
|
||||
// We want the int value, not the string.
|
||||
id = Emu.GetUsrId();
|
||||
}
|
||||
|
||||
if (!stat)
|
||||
@ -121,8 +121,8 @@ error_code cellUserInfoGetList(vm::ptr<u32> listNum, vm::ptr<CellUserInfoUserLis
|
||||
|
||||
if (currentUserId)
|
||||
{
|
||||
// TODO: Properly set the current user ID here, once implemented
|
||||
*currentUserId = 1;
|
||||
// We want the int value, not the string.
|
||||
*currentUserId = Emu.GetUsrId();
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
|
@ -65,8 +65,7 @@ s32 npDrmIsAvailable(vm::cptr<u8> k_licensee_addr, vm::cptr<char> drm_path)
|
||||
npdrmkeys->devKlic.fill(0);
|
||||
npdrmkeys->rifKey.fill(0);
|
||||
|
||||
// todo: profile for rap_dir_path
|
||||
std::string rap_dir_path = "/dev_hdd0/home/00000001/exdata/";
|
||||
std::string rap_dir_path = fmt::format("/dev_hdd0/home/%s/exdata/", Emu.GetUsr());
|
||||
|
||||
const std::string& enc_drm_path_local = vfs::get(enc_drm_path);
|
||||
const fs::file enc_file(enc_drm_path_local);
|
||||
@ -145,7 +144,7 @@ s32 sceNpDrmVerifyUpgradeLicense(vm::cptr<char> content_id)
|
||||
return SCE_NP_DRM_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!fs::is_file(vfs::get("/dev_hdd0/home/00000001/exdata/") + content_id.get_ptr() + ".rap"))
|
||||
if (!fs::is_file(vfs::get(fmt::format("/dev_hdd0/home/%s/exdata/%s.rap", Emu.GetUsr(), content_id.get_ptr()))))
|
||||
{
|
||||
// Game hasn't been purchased therefore no RAP file present
|
||||
return SCE_NP_DRM_ERROR_LICENSE_NOT_FOUND;
|
||||
@ -164,7 +163,7 @@ s32 sceNpDrmVerifyUpgradeLicense2(vm::cptr<char> content_id)
|
||||
return SCE_NP_DRM_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!fs::is_file(vfs::get("/dev_hdd0/home/00000001/exdata/") + content_id.get_ptr() + ".rap"))
|
||||
if (!fs::is_file(vfs::get(fmt::format("/dev_hdd0/home/%s/exdata/%s.rap", Emu.GetUsr(), content_id.get_ptr()))))
|
||||
{
|
||||
// Game hasn't been purchased therefore no RAP file present
|
||||
return SCE_NP_DRM_ERROR_LICENSE_NOT_FOUND;
|
||||
|
@ -296,8 +296,7 @@ error_code sceNpTrophyRegisterContext(ppu_thread& ppu, u32 context, u32 handle,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Get the path of the current user
|
||||
std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name;
|
||||
std::string trophyPath = fmt::format("/dev_hdd0/home/%s/trophy/%s", Emu.GetUsr(), ctxt->trp_name);
|
||||
if (!trp.Install(trophyPath))
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE;
|
||||
@ -346,7 +345,7 @@ error_code sceNpTrophyGetRequiredDiskSpace(u32 context, u32 handle, vm::ptr<u64>
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
if (!fs::is_dir(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name)))
|
||||
if (!fs::is_dir(vfs::get(fmt::format("/dev_hdd0/home/%s/trophy/%s", Emu.GetUsr(), ctxt->trp_name))))
|
||||
{
|
||||
TRPLoader trp(ctxt->trp_stream);
|
||||
|
||||
@ -405,8 +404,7 @@ error_code sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptr<SceNpTrophyGa
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
// TODO: Get the path of the current user
|
||||
fs::file config(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM"));
|
||||
fs::file config(vfs::get(fmt::format("/dev_hdd0/home/%s/trophy/%s/TROPCONF.SFM", Emu.GetUsr(), ctxt->trp_name)));
|
||||
|
||||
if (!config)
|
||||
{
|
||||
@ -505,7 +503,7 @@ error_code sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::pt
|
||||
return SCE_NP_TROPHY_ERROR_ALREADY_UNLOCKED;
|
||||
|
||||
ctxt->tropusr->UnlockTrophy(trophyId, 0, 0); // TODO
|
||||
std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPUSR.DAT";
|
||||
std::string trophyPath = fmt::format("/dev_hdd0/home/%s/trophy/%s/TROPUSR.DAT", Emu.GetUsr(), ctxt->trp_name);
|
||||
ctxt->tropusr->Save(trophyPath);
|
||||
|
||||
if (platinumId)
|
||||
@ -527,7 +525,8 @@ error_code sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::pt
|
||||
}
|
||||
|
||||
// Get icon for the notification.
|
||||
std::string trophyIconPath = "/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROP" + padding + std::to_string(trophyId) + ".PNG";
|
||||
std::string paddedTrophyId = padding + std::to_string(trophyId);
|
||||
std::string trophyIconPath = fmt::format("/dev_hdd0/home/%s/trophy/%s/TROP%s.PNG", Emu.GetUsr(), ctxt->trp_name, paddedTrophyId);
|
||||
fs::file trophyIconFile = fs::file(vfs::get(trophyIconPath));
|
||||
size_t iconSize = trophyIconFile.size();
|
||||
std::vector<uchar> trophyIconData;
|
||||
@ -612,8 +611,7 @@ error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::p
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
// TODO: Get the path of the current user
|
||||
fs::file config(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM"));
|
||||
fs::file config(vfs::get(fmt::format("/dev_hdd0/home/%s/trophy/%s/TROPCONF.SFM", Emu.GetUsr(), ctxt->trp_name)));
|
||||
|
||||
if (!config)
|
||||
{
|
||||
@ -756,7 +754,7 @@ error_code sceNpTrophyGetGameIcon(u32 context, u32 handle, vm::ptr<void> buffer,
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
fs::file icon_file(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/ICON0.PNG"));
|
||||
fs::file icon_file(vfs::get(fmt::format("/dev_hdd0/home/%s/trophy/%s/ICON0.PNG", Emu.GetUsr(), ctxt->trp_name)));
|
||||
|
||||
if (!icon_file)
|
||||
{
|
||||
@ -809,7 +807,7 @@ error_code sceNpTrophyGetTrophyIcon(u32 context, u32 handle, s32 trophyId, vm::p
|
||||
return hidden ? SCE_NP_TROPHY_ERROR_HIDDEN : SCE_NP_TROPHY_ERROR_LOCKED;
|
||||
}
|
||||
|
||||
fs::file icon_file(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + fmt::format("/TROP%03d.PNG", trophyId)));
|
||||
fs::file icon_file(vfs::get(fmt::format("/dev_hdd0/home/%s/trophy/%s/TROP%03d.PNG", Emu.GetUsr(), ctxt->trp_name, trophyId)));
|
||||
|
||||
if (!icon_file)
|
||||
{
|
||||
|
@ -278,10 +278,14 @@ void Emulator::Init()
|
||||
|
||||
// Create directories
|
||||
const std::string emu_dir = GetEmuDir();
|
||||
const std::string dev_hdd0 = fmt::replace_all(g_cfg.vfs.dev_hdd0, "$(EmulatorDir)", emu_dir);
|
||||
const std::string dev_hdd0 = GetHddDir();
|
||||
const std::string dev_hdd1 = fmt::replace_all(g_cfg.vfs.dev_hdd1, "$(EmulatorDir)", emu_dir);
|
||||
const std::string dev_usb = fmt::replace_all(g_cfg.vfs.dev_usb000, "$(EmulatorDir)", emu_dir);
|
||||
|
||||
// Set selected user.
|
||||
m_usr = g_cfg.usr.selected_usr;
|
||||
m_usrid = static_cast<u32>(std::stoul(m_usr));
|
||||
|
||||
fs::create_path(dev_hdd0);
|
||||
fs::create_path(dev_hdd1);
|
||||
fs::create_path(dev_usb);
|
||||
@ -290,11 +294,11 @@ void Emulator::Init()
|
||||
fs::create_dir(dev_hdd0 + "game/TEST12345/USRDIR/");
|
||||
fs::create_dir(dev_hdd0 + "game/.locks/");
|
||||
fs::create_dir(dev_hdd0 + "home/");
|
||||
fs::create_dir(dev_hdd0 + "home/00000001/");
|
||||
fs::create_dir(dev_hdd0 + "home/00000001/exdata/");
|
||||
fs::create_dir(dev_hdd0 + "home/00000001/savedata/");
|
||||
fs::create_dir(dev_hdd0 + "home/00000001/trophy/");
|
||||
fs::write_file(dev_hdd0 + "home/00000001/localusername", fs::create + fs::excl + fs::write, "User"s);
|
||||
fs::create_dir(dev_hdd0 + "home/" + m_usr + "/");
|
||||
fs::create_dir(dev_hdd0 + "home/" + m_usr + "/exdata/");
|
||||
fs::create_dir(dev_hdd0 + "home/" + m_usr + "/savedata/");
|
||||
fs::create_dir(dev_hdd0 + "home/" + m_usr + "/trophy/");
|
||||
fs::write_file(dev_hdd0 + "home/" + m_usr + "/localusername", fs::create + fs::excl + fs::write, "User"s);
|
||||
fs::create_dir(dev_hdd0 + "disc/");
|
||||
fs::create_dir(dev_hdd0 + "savedata/");
|
||||
fs::create_dir(dev_hdd0 + "savedata/vmc/");
|
||||
|
@ -209,6 +209,8 @@ class Emulator final
|
||||
std::string m_title;
|
||||
std::string m_cat;
|
||||
std::string m_dir;
|
||||
std::string m_usr;
|
||||
u32 m_usrid;
|
||||
|
||||
bool m_force_boot = false;
|
||||
|
||||
@ -277,6 +279,18 @@ public:
|
||||
return m_dir;
|
||||
}
|
||||
|
||||
// String for GUI dialogs.
|
||||
const std::string& GetUsr() const
|
||||
{
|
||||
return m_usr;
|
||||
}
|
||||
|
||||
// u32 for cell.
|
||||
const u32 GetUsrId() const
|
||||
{
|
||||
return m_usrid;
|
||||
}
|
||||
|
||||
u64 GetPauseTime()
|
||||
{
|
||||
return m_pause_amend_time;
|
||||
@ -491,6 +505,15 @@ struct cfg_root : cfg::node
|
||||
|
||||
} net{this};
|
||||
|
||||
struct node_usr : cfg::node
|
||||
{
|
||||
node_usr(cfg::node* _this) : cfg::node(_this, "User") {}
|
||||
|
||||
// This is only a default, will get read from existing config.yml.
|
||||
cfg::string selected_usr{ this, "Selected User", "00000001" };
|
||||
|
||||
} usr{this};
|
||||
|
||||
struct node_misc : cfg::node
|
||||
{
|
||||
node_misc(cfg::node* _this) : cfg::node(_this, "Miscellaneous") {}
|
||||
|
@ -481,6 +481,11 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_user_manager_dialog.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_vfs_dialog.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
@ -636,6 +641,11 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QTGeneratedFiles\Debug\moc_user_manager_dialog.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QTGeneratedFiles\Debug\moc_vfs_dialog.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
@ -811,6 +821,11 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_user_manager_dialog.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_vfs_dialog.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
@ -966,6 +981,11 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QTGeneratedFiles\Release\moc_user_manager_dialog.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QTGeneratedFiles\Release\moc_vfs_dialog.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
@ -998,6 +1018,8 @@
|
||||
<ClCompile Include="rpcs3qt\trophy_manager_dialog.cpp" />
|
||||
<ClCompile Include="rpcs3qt\trophy_notification_frame.cpp" />
|
||||
<ClCompile Include="rpcs3qt\trophy_notification_helper.cpp" />
|
||||
<ClCompile Include="rpcs3qt\user_account.cpp" />
|
||||
<ClCompile Include="rpcs3qt\user_manager_dialog.cpp" />
|
||||
<ClCompile Include="rpcs3qt\vfs_dialog.cpp" />
|
||||
<ClCompile Include="rpcs3qt\vfs_dialog_tab.cpp" />
|
||||
<ClCompile Include="rpcs3qt\welcome_dialog.cpp" />
|
||||
@ -1605,6 +1627,24 @@
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DLLVM_AVAILABLE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE "-I$(VULKAN_SDK)\Include" "-I.\.." "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)\." "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="rpcs3qt\user_manager_dialog.h">
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">Moc%27ing %(Identity)...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DBRANCH= -DLLVM_AVAILABLE -D_UNICODE "-I.\..\Vulkan\Vulkan-LoaderAndValidationLayers\include" "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtQuick" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)\." "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Identity)...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -D_SCL_SECURE_NO_WARNINGS -D_UNICODE "-I.\..\Vulkan\Vulkan-LoaderAndValidationLayers\include" "-I.\.." "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtQuick" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)\." "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing %(Identity)...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -D_UNICODE "-I.\..\Vulkan\Vulkan-LoaderAndValidationLayers\include" "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtQuick" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)\." "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">Moc%27ing %(Identity)...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DLLVM_AVAILABLE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE "-I.\..\Vulkan\Vulkan-LoaderAndValidationLayers\include" "-I.\.." "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtQuick" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)\." "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="rpcs3qt\table_item_delegate.h" />
|
||||
<CustomBuild Include="rpcs3qt\welcome_dialog.h">
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">Moc%27ing welcome_dialog.h...</Message>
|
||||
@ -1663,6 +1703,7 @@
|
||||
<ClInclude Include="rpcs3qt\trophy_manager_dialog.h" />
|
||||
<ClInclude Include="rpcs3qt\trophy_notification_frame.h" />
|
||||
<ClInclude Include="rpcs3qt\trophy_notification_helper.h" />
|
||||
<ClInclude Include="rpcs3qt\user_account.h" />
|
||||
<ClInclude Include="xinput_pad_handler.h" />
|
||||
<ClInclude Include="\rpcs3qt\*.h" />
|
||||
</ItemGroup>
|
||||
|
@ -102,6 +102,9 @@
|
||||
<Filter Include="Gui\utils">
|
||||
<UniqueIdentifier>{77ca7382-c296-43af-adb4-fb32f5ab4571}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Gui\user accounts">
|
||||
<UniqueIdentifier>{bebec4fb-789c-4456-a838-5ba7e158af5c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="\rpcs3qt\*.cpp">
|
||||
@ -599,6 +602,24 @@
|
||||
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_register_editor_dialog.cpp">
|
||||
<Filter>Generated Files\Debug - LLVM</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="rpcs3qt\user_manager_dialog.cpp">
|
||||
<Filter>Gui\user accounts</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="rpcs3qt\user_account.cpp">
|
||||
<Filter>Gui\user accounts</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_user_manager_dialog.cpp">
|
||||
<Filter>Generated Files\Release - LLVM</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QTGeneratedFiles\Debug\moc_user_manager_dialog.cpp">
|
||||
<Filter>Generated Files\Debug</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QTGeneratedFiles\Release\moc_user_manager_dialog.cpp">
|
||||
<Filter>Generated Files\Release</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_user_manager_dialog.cpp">
|
||||
<Filter>Generated Files\Debug - LLVM</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="rpcs3qt\breakpoint_handler.cpp">
|
||||
<Filter>Gui\debugger</Filter>
|
||||
</ClCompile>
|
||||
@ -718,6 +739,9 @@
|
||||
<ClInclude Include="rpcs3qt\custom_dock_widget.h">
|
||||
<Filter>Gui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="rpcs3qt\user_account.h">
|
||||
<Filter>Gui\user accounts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="rpcs3qt\_discord_utils.h">
|
||||
<Filter>Gui\utils</Filter>
|
||||
</ClInclude>
|
||||
@ -840,6 +864,9 @@
|
||||
<CustomBuild Include="rpcs3qt\register_editor_dialog.h">
|
||||
<Filter>Gui\debugger</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="rpcs3qt\user_manager_dialog.h">
|
||||
<Filter>Gui\user accounts</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="rpcs3qt\debugger_list.h">
|
||||
<Filter>Gui\debugger</Filter>
|
||||
</CustomBuild>
|
||||
|
@ -110,6 +110,9 @@ public:
|
||||
// Network
|
||||
ConnectionStatus,
|
||||
|
||||
// User
|
||||
SelectedUser,
|
||||
|
||||
// Language
|
||||
Language,
|
||||
EnableHostRoot,
|
||||
@ -287,6 +290,9 @@ private:
|
||||
// Networking
|
||||
{ ConnectionStatus, { "Net", "Connection status"}},
|
||||
|
||||
// User
|
||||
{SelectedUser, {"User", "Selected User"}},
|
||||
|
||||
// System
|
||||
{ Language, { "System", "Language"}},
|
||||
{ EnableHostRoot, { "VFS", "Enable /host_root/"}},
|
||||
|
@ -126,6 +126,7 @@ namespace gui
|
||||
const QString gs_frame = "GSFrame";
|
||||
const QString trophy = "Trophy";
|
||||
const QString savedata = "SaveData";
|
||||
const QString users = "Users";
|
||||
const QString notes = "Notes";
|
||||
|
||||
const QColor gl_icon_color = QColor(36, 36, 36, 255);
|
||||
@ -216,6 +217,8 @@ namespace gui
|
||||
const gui_save tr_trophy_state = gui_save(trophy, "trophy_state", QByteArray());
|
||||
|
||||
const gui_save sd_geometry = gui_save(savedata, "geometry", QByteArray());
|
||||
|
||||
const gui_save um_geometry = gui_save(users, "geometry", QByteArray());
|
||||
}
|
||||
|
||||
/** Class for GUI settings..
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "vfs_dialog.h"
|
||||
#include "save_manager_dialog.h"
|
||||
#include "trophy_manager_dialog.h"
|
||||
#include "user_manager_dialog.h"
|
||||
#include "kernel_explorer.h"
|
||||
#include "game_list_frame.h"
|
||||
#include "debugger_frame.h"
|
||||
@ -891,6 +892,8 @@ void main_window::OnEmuStop()
|
||||
ui->toolbar_start->setText(tr("Play"));
|
||||
ui->toolbar_start->setToolTip(Emu.IsReady() ? tr("Start emulation") : tr("Resume emulation"));
|
||||
}
|
||||
ui->actionManage_Users->setEnabled(true);
|
||||
|
||||
#ifdef WITH_DISCORD_RPC
|
||||
// Discord Rich Presence Integration
|
||||
if (guiSettings->GetValue(gui::m_richPresence).toBool())
|
||||
@ -913,6 +916,8 @@ void main_window::OnEmuReady()
|
||||
ui->toolbar_start->setText(tr("Play"));
|
||||
ui->toolbar_start->setToolTip(Emu.IsReady() ? tr("Start emulation") : tr("Resume emulation"));
|
||||
EnableMenus(true);
|
||||
|
||||
ui->actionManage_Users->setEnabled(false);
|
||||
}
|
||||
|
||||
void main_window::EnableMenus(bool enabled)
|
||||
@ -1262,6 +1267,12 @@ void main_window::CreateConnects()
|
||||
trop_manager->show();
|
||||
});
|
||||
|
||||
connect(ui->actionManage_Users, &QAction::triggered, [=]
|
||||
{
|
||||
user_manager_dialog* user_manager = new user_manager_dialog(guiSettings, emuSettings, "", this);
|
||||
user_manager->show();
|
||||
});
|
||||
|
||||
connect(ui->toolsCgDisasmAct, &QAction::triggered, [=]
|
||||
{
|
||||
cg_disasm_window* cgdw = new cg_disasm_window(guiSettings);
|
||||
@ -1778,8 +1789,7 @@ void main_window::dropEvent(QDropEvent* event)
|
||||
{
|
||||
const std::string rapname = sstr(QFileInfo(rap).fileName());
|
||||
|
||||
// TODO: use correct user ID once User Manager is implemented
|
||||
if (!fs::copy_file(sstr(rap), fmt::format("%s/home/%s/exdata/%s", Emu.GetHddDir(), "00000001", rapname), false))
|
||||
if (!fs::copy_file(sstr(rap), fmt::format("%s/home/%s/exdata/%s", Emu.GetHddDir(), Emu.GetUsr(), rapname), false))
|
||||
{
|
||||
LOG_WARNING(GENERAL, "Could not copy rap file by drop: %s", rapname);
|
||||
}
|
||||
|
@ -502,7 +502,7 @@
|
||||
</action>
|
||||
<action name="actionManage_Users">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>User Accounts</string>
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <QPushButton>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include "Emu/System.h"
|
||||
|
||||
constexpr auto qstr = QString::fromStdString;
|
||||
|
||||
@ -60,7 +61,7 @@ void save_data_info_dialog::UpdateData()
|
||||
|
||||
//Maybe there should be more details of save data.
|
||||
m_list->setItem(0, 0, new QTableWidgetItem(tr("User ID")));
|
||||
m_list->setItem(0, 1, new QTableWidgetItem("00000001 (Default)"));
|
||||
m_list->setItem(0, 1, new QTableWidgetItem(qstr(Emu.GetUsr())));
|
||||
|
||||
m_list->setItem(1, 0, new QTableWidgetItem(tr("Title")));
|
||||
m_list->setItem(1, 1, new QTableWidgetItem(qstr(m_entry.title)));
|
||||
|
@ -146,7 +146,8 @@ void save_manager_dialog::UpdateList()
|
||||
{
|
||||
if (m_dir == "")
|
||||
{
|
||||
m_dir = Emu.GetHddDir() + "home/00000001/savedata/";
|
||||
// fmt::format(%shome ... is harder to read than straight concatenation.
|
||||
m_dir = Emu.GetHddDir() + "home/" + Emu.GetUsr() + "/savedata/";
|
||||
}
|
||||
|
||||
m_save_entries = GetSaveEntries(m_dir);
|
||||
|
@ -29,8 +29,6 @@
|
||||
#include <QScrollBar>
|
||||
#include <QWheelEvent>
|
||||
|
||||
static const char* m_TROPHY_DIR = "/dev_hdd0/home/00000001/trophy/";
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr auto qstr = QString::fromStdString;
|
||||
@ -58,6 +56,10 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr<gui_settings> gui_s
|
||||
// HACK: dev_hdd0 must be mounted for vfs to work for loading trophies.
|
||||
vfs::mount("dev_hdd0", Emu.GetHddDir());
|
||||
|
||||
|
||||
// Get the currently selected user's trophy path.
|
||||
m_trophy_dir = fmt::format("/dev_hdd0/home/%s/trophy/", Emu.GetUsr());
|
||||
|
||||
// Game chooser combo box
|
||||
m_game_combo = new QComboBox();
|
||||
m_game_combo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
|
||||
@ -320,7 +322,7 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr<gui_settings> gui_s
|
||||
|
||||
bool trophy_manager_dialog::LoadTrophyFolderToDB(const std::string& trop_name)
|
||||
{
|
||||
std::string trophyPath = m_TROPHY_DIR + trop_name;
|
||||
std::string trophyPath = m_trophy_dir + trop_name;
|
||||
|
||||
// Populate GameTrophiesData
|
||||
std::unique_ptr<GameTrophiesData> game_trophy_data = std::make_unique<GameTrophiesData>();
|
||||
|
@ -106,6 +106,7 @@ private:
|
||||
bool m_show_silver_trophies = true;
|
||||
bool m_show_gold_trophies = true;
|
||||
bool m_show_platinum_trophies = true;
|
||||
std::string m_trophy_dir;
|
||||
|
||||
int m_icon_height = 75;
|
||||
bool m_save_icon_height = false;
|
||||
|
27
rpcs3/rpcs3qt/user_account.cpp
Normal file
27
rpcs3/rpcs3qt/user_account.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "user_account.h"
|
||||
|
||||
UserAccount::UserAccount(const std::string& userId)
|
||||
{
|
||||
// Setting userId.
|
||||
m_userId = userId;
|
||||
|
||||
// Setting userDir.
|
||||
m_userDir = Emu.GetHddDir() + "home/" + m_userId + "/";
|
||||
|
||||
// Setting userName.
|
||||
fs::file file;
|
||||
if (file.open(m_userDir + "localusername", fs::read))
|
||||
{
|
||||
file.read(m_userName, 16*sizeof(char)); //max of 16 chars on real PS3
|
||||
file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING(GENERAL, "UserAccount: localusername file read error (userId=%s, userDir=%s).", m_userId, m_userDir);
|
||||
}
|
||||
}
|
||||
|
||||
UserAccount::~UserAccount()
|
||||
{
|
||||
}
|
||||
|
26
rpcs3/rpcs3qt/user_account.h
Normal file
26
rpcs3/rpcs3qt/user_account.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "Emu/System.h"
|
||||
#include "Utilities/File.h"
|
||||
#include "Utilities/StrFmt.h"
|
||||
|
||||
// Do not confuse this with the "user" in Emu/System.h.
|
||||
// That user is read from config.yml, and it only represents the currently "logged in" user.
|
||||
// The UserAccount class will represent all users in the home directory for the User Manager dialog.
|
||||
// Selecting a user account in this dialog and saving writes it to config.yml.
|
||||
class UserAccount
|
||||
{
|
||||
public:
|
||||
explicit UserAccount(const std::string& userId);
|
||||
|
||||
std::string GetUserId() { return m_userId; };
|
||||
std::string GetUserDir() { return m_userDir; };
|
||||
std::string GetUserName() { return m_userName; };
|
||||
~UserAccount();
|
||||
|
||||
private:
|
||||
std::string m_userId;
|
||||
std::string m_userDir;
|
||||
std::string m_userName;
|
||||
|
||||
};
|
371
rpcs3/rpcs3qt/user_manager_dialog.cpp
Normal file
371
rpcs3/rpcs3qt/user_manager_dialog.cpp
Normal file
@ -0,0 +1,371 @@
|
||||
#include "user_manager_dialog.h"
|
||||
|
||||
#include "Utilities/StrUtil.h"
|
||||
|
||||
#include <QRegExpValidator>
|
||||
#include <QInputDialog>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::vector<UserAccount*> GetUserAccounts(const std::string& base_dir)
|
||||
{
|
||||
std::vector<UserAccount*> user_list;
|
||||
|
||||
// I believe this gets the folder list sorted alphabetically by default,
|
||||
// but I can't find proof of this always being true.
|
||||
for (const auto& userFolder : fs::dir(base_dir))
|
||||
{
|
||||
if (!userFolder.is_directory)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Is the folder name exactly 8 all-numerical characters long?
|
||||
// We use strtol to find any non-numeric characters in folder name.
|
||||
char* nonNumericChar;
|
||||
std::strtol(userFolder.name.c_str(), &nonNumericChar, 10);
|
||||
if (userFolder.name.length() != 8 || *nonNumericChar != '\0')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Does the localusername file exist?
|
||||
if (!fs::is_file(fmt::format("%s/%s/localusername", base_dir, userFolder.name)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UserAccount* user_entry = new UserAccount(userFolder.name);
|
||||
user_list.emplace_back(user_entry);
|
||||
}
|
||||
return user_list;
|
||||
}
|
||||
}
|
||||
|
||||
user_manager_dialog::user_manager_dialog(std::shared_ptr<gui_settings> gui_settings, std::shared_ptr<emu_settings> emu_settings, const std::string& dir, QWidget* parent)
|
||||
: QDialog(parent), m_user_list(), m_dir(dir), m_sort_column(1), m_sort_ascending(true), m_gui_settings(gui_settings), m_emu_settings(emu_settings)
|
||||
{
|
||||
setWindowTitle(tr("User Manager"));
|
||||
setMinimumSize(QSize(400, 400));
|
||||
setModal(true);
|
||||
|
||||
m_emu_settings->LoadSettings();
|
||||
Init(dir);
|
||||
}
|
||||
|
||||
void user_manager_dialog::Init(const std::string& dir)
|
||||
{
|
||||
// Table
|
||||
m_table = new QTableWidget(this);
|
||||
|
||||
//m_table->setItemDelegate(new table_item_delegate(this)); // to get rid of cell selection rectangles include "table_item_delegate.h"
|
||||
m_table->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
|
||||
m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
m_table->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_table->setColumnCount(2);
|
||||
m_table->setHorizontalHeaderLabels(QStringList() << tr("User ID") << tr("User Name"));
|
||||
|
||||
QPushButton* push_remove_user = new QPushButton(tr("Delete User"), this);
|
||||
QPushButton* push_create_user = new QPushButton(tr("Create User"), this);
|
||||
QPushButton* push_login_user = new QPushButton(tr("Log In User"), this);
|
||||
QPushButton* push_rename_user = new QPushButton(tr("Rename User"), this);
|
||||
|
||||
QPushButton* push_close = new QPushButton(tr("&Close"), this);
|
||||
push_close->setAutoDefault(true);
|
||||
|
||||
// Button Layout
|
||||
QHBoxLayout* hbox_buttons = new QHBoxLayout();
|
||||
hbox_buttons->addWidget(push_create_user);
|
||||
hbox_buttons->addWidget(push_login_user);
|
||||
hbox_buttons->addWidget(push_rename_user);
|
||||
hbox_buttons->addWidget(push_remove_user);
|
||||
hbox_buttons->addStretch();
|
||||
hbox_buttons->addWidget(push_close);
|
||||
|
||||
// main layout
|
||||
QVBoxLayout* vbox_main = new QVBoxLayout();
|
||||
vbox_main->setAlignment(Qt::AlignCenter);
|
||||
vbox_main->addWidget(m_table);
|
||||
vbox_main->addLayout(hbox_buttons);
|
||||
setLayout(vbox_main);
|
||||
|
||||
m_selected_user = m_emu_settings->GetSetting(emu_settings::SelectedUser);
|
||||
UpdateTable();
|
||||
|
||||
restoreGeometry(m_gui_settings->GetValue(gui::um_geometry).toByteArray());
|
||||
|
||||
// Use this in multiple connects to protect the current user from deletion/rename.
|
||||
auto enableButtons = [=]()
|
||||
{
|
||||
int idx = m_table->currentRow();
|
||||
if (idx < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int idx_real = m_table->item(idx, 0)->data(Qt::UserRole).toInt();
|
||||
std::string idx_user = m_user_list[idx_real]->GetUserId();
|
||||
bool enable = idx_user != m_selected_user;
|
||||
|
||||
push_rename_user->setEnabled(enable);
|
||||
push_remove_user->setEnabled(enable);
|
||||
};
|
||||
|
||||
// Connects and events
|
||||
connect(push_close, &QAbstractButton::clicked, this, &user_manager_dialog::close);
|
||||
connect(push_remove_user, &QAbstractButton::clicked, this, &user_manager_dialog::OnUserRemove);
|
||||
connect(push_rename_user, &QAbstractButton::clicked, this, &user_manager_dialog::OnUserRename);
|
||||
connect(push_create_user, &QAbstractButton::clicked, this, &user_manager_dialog::OnUserCreate);
|
||||
connect(push_login_user, &QAbstractButton::clicked, this, &user_manager_dialog::OnUserLogin);
|
||||
connect(this, &user_manager_dialog::OnUserLoginSuccess, this, enableButtons);
|
||||
connect(m_table, &QTableWidget::itemDoubleClicked, this, &user_manager_dialog::OnUserLogin);
|
||||
connect(m_table->horizontalHeader(), &QHeaderView::sectionClicked, this, &user_manager_dialog::OnSort);
|
||||
connect(m_table, &QTableWidget::customContextMenuRequested, this, &user_manager_dialog::ShowContextMenu);
|
||||
connect(m_table, &QTableWidget::itemClicked, this, enableButtons);
|
||||
connect(m_table, &QTableWidget::itemSelectionChanged, this, enableButtons);
|
||||
}
|
||||
|
||||
void user_manager_dialog::UpdateTable()
|
||||
{
|
||||
if (m_dir == "")
|
||||
{
|
||||
// fmt::format(%shome ... is harder to read than straight concatenation.
|
||||
m_dir = Emu.GetHddDir() + "home";
|
||||
}
|
||||
|
||||
// Get the user folders in the home directory and the currently logged in user.
|
||||
m_user_list.clear();
|
||||
m_user_list = GetUserAccounts(m_dir);
|
||||
|
||||
// Clear and then repopulate the table with the list gathered above.
|
||||
m_table->setRowCount(static_cast<int>(m_user_list.size()));
|
||||
|
||||
// For indicating logged-in user.
|
||||
QFont boldFont;
|
||||
boldFont.setBold(true);
|
||||
|
||||
int row = 0;
|
||||
for (UserAccount* user : m_user_list)
|
||||
{
|
||||
QString userId = qstr(user->GetUserId());
|
||||
QString userName = qstr(user->GetUserName());
|
||||
|
||||
QTableWidgetItem* userIdItem = new QTableWidgetItem(userId);
|
||||
userIdItem->setData(Qt::UserRole, row); // For sorting to work properly
|
||||
userIdItem->setFlags(userIdItem->flags() & ~Qt::ItemIsEditable);
|
||||
m_table->setItem(row, 0, userIdItem);
|
||||
|
||||
QTableWidgetItem* userNameItem = new QTableWidgetItem(userName);
|
||||
userNameItem->setData(Qt::UserRole, row); // For sorting to work properly
|
||||
userNameItem->setFlags(userNameItem->flags() & ~Qt::ItemIsEditable);
|
||||
m_table->setItem(row, 1, userNameItem);
|
||||
|
||||
// Compare current config value with the one in this user (only 8 digits in userId)
|
||||
if (m_selected_user.compare(0, 8, user->GetUserId()) == 0)
|
||||
{
|
||||
userIdItem->setFont(boldFont);
|
||||
userNameItem->setFont(boldFont);
|
||||
}
|
||||
++row;
|
||||
}
|
||||
// GUI resizing
|
||||
m_table->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
|
||||
m_table->verticalHeader()->resizeSections(QHeaderView::ResizeToContents);
|
||||
|
||||
QSize tableSize = QSize(
|
||||
m_table->verticalHeader()->width() + m_table->horizontalHeader()->length() + m_table->frameWidth() * 2,
|
||||
m_table->horizontalHeader()->height() + m_table->verticalHeader()->length() + m_table->frameWidth() * 2);
|
||||
|
||||
QSize preferredSize = minimumSize().expandedTo(sizeHint() - m_table->sizeHint() + tableSize).expandedTo(size());
|
||||
QSize maxSize = QSize(preferredSize.width(), static_cast<int>(QApplication::desktop()->screenGeometry().height()*.6));
|
||||
|
||||
resize(preferredSize.boundedTo(maxSize));
|
||||
}
|
||||
|
||||
//Remove a user folder, needs to be confirmed.
|
||||
void user_manager_dialog::OnUserRemove()
|
||||
{
|
||||
int idx = m_table->currentRow();
|
||||
int idx_real = m_table->item(idx, 0)->data(Qt::UserRole).toInt();
|
||||
if (QMessageBox::question(this, tr("Delete Confirmation"), tr("Are you sure you want to delete:\n%1?").arg(qstr(m_user_list[idx_real]->GetUserName())), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
|
||||
{
|
||||
fs::remove_all(m_user_list[idx_real]->GetUserDir());
|
||||
UpdateTable();
|
||||
}
|
||||
}
|
||||
|
||||
void user_manager_dialog::GenerateUser(const std::string& username)
|
||||
{
|
||||
// If the user list is sorted by defult from fs::dir, then we just need the last one in the list.
|
||||
std::string largestUserId = m_user_list[m_user_list.size() - 1]->GetUserId();
|
||||
|
||||
// Add one to the largest user id, then reformat the result into an 8-digit string.
|
||||
u8 nextLargest = static_cast<u8>(std::stoul(largestUserId) + 1u);
|
||||
char* buf;
|
||||
sprintf(buf, "%08d", nextLargest);
|
||||
std::string nextUserId(buf);
|
||||
|
||||
// Create user folders and such.
|
||||
const std::string homeDir = Emu.GetHddDir() + "home/";
|
||||
const std::string userDir = homeDir + nextUserId;
|
||||
fs::create_dir(homeDir);
|
||||
fs::create_dir(fmt::format("%s/", userDir));
|
||||
fs::create_dir(fmt::format("%s/exdata/", userDir));
|
||||
fs::create_dir(fmt::format("%s/savedata/", userDir));
|
||||
fs::create_dir(fmt::format("%s/trophy/", userDir));
|
||||
fs::write_file(fmt::format("%s/localusername", userDir), fs::create + fs::excl + fs::write, username);
|
||||
}
|
||||
|
||||
bool user_manager_dialog::ValidateUsername(const QString& textToValidate)
|
||||
{
|
||||
// "Entire string (^...$) must be between 3 and 16 characters
|
||||
// and only consist of letters, numbers, underscores, and hyphens."
|
||||
QRegExpValidator validator(QRegExp("^[A-Za-z0-9_-]{3,16}$"));
|
||||
|
||||
int pos = 0;
|
||||
QString text = textToValidate;
|
||||
return (validator.validate(text, pos) == QValidator::Acceptable);
|
||||
}
|
||||
|
||||
void user_manager_dialog::OnUserRename()
|
||||
{
|
||||
QInputDialog* dialog = new QInputDialog(this);
|
||||
dialog->setWindowTitle(tr("Rename User"));
|
||||
dialog->setLabelText(tr("New Username: "));
|
||||
dialog->resize(200, 100);
|
||||
|
||||
while (dialog->exec() != QDialog::Rejected)
|
||||
{
|
||||
dialog->resize(200, 100);
|
||||
QString textToValidate = dialog->textValue();
|
||||
if (!ValidateUsername(textToValidate))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Error"), tr("Name must be between 3 and 16 characters and only consist of letters, numbers, underscores, and hyphens."));
|
||||
continue;
|
||||
}
|
||||
int idx = m_table->currentRow();
|
||||
int idx_real = m_table->item(idx, 0)->data(Qt::UserRole).toInt();
|
||||
|
||||
const std::string userId = m_user_list[idx_real]->GetUserId();
|
||||
const std::string usernameFile = Emu.GetHddDir() + "home/" + userId + "/localusername";
|
||||
fs::write_file(usernameFile, fs::rewrite, textToValidate.toStdString());
|
||||
UpdateTable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void user_manager_dialog::OnUserCreate()
|
||||
{
|
||||
QInputDialog* dialog = new QInputDialog(this);
|
||||
dialog->setWindowTitle(tr("New User"));
|
||||
dialog->setLabelText(tr("New Username: "));
|
||||
dialog->resize(200, 100);
|
||||
|
||||
while (dialog->exec() != QDialog::Rejected)
|
||||
{
|
||||
dialog->resize(200, 100);
|
||||
QString textToValidate = dialog->textValue();
|
||||
if (!ValidateUsername(textToValidate))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Error"), tr("Name must be between 3 and 16 characters and only consist of letters, numbers, underscores, and hyphens."));
|
||||
continue;
|
||||
}
|
||||
GenerateUser(textToValidate.toStdString());
|
||||
UpdateTable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void user_manager_dialog::OnUserLogin()
|
||||
{
|
||||
int idx = m_table->currentRow();
|
||||
int idx_real = m_table->item(idx, 0)->data(Qt::UserRole).toInt();
|
||||
std::string selectedUserId = m_user_list[idx_real]->GetUserId();
|
||||
|
||||
m_selected_user = selectedUserId;
|
||||
m_emu_settings->SetSetting(emu_settings::SelectedUser, m_selected_user);
|
||||
m_emu_settings->SaveSettings();
|
||||
UpdateTable();
|
||||
Q_EMIT OnUserLoginSuccess();
|
||||
}
|
||||
|
||||
void user_manager_dialog::OnSort(int logicalIndex)
|
||||
{
|
||||
if (logicalIndex < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (logicalIndex == m_sort_column)
|
||||
{
|
||||
m_sort_ascending ^= true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sort_ascending = true;
|
||||
}
|
||||
Qt::SortOrder sort_order = m_sort_ascending ? Qt::AscendingOrder : Qt::DescendingOrder;
|
||||
m_table->sortByColumn(m_sort_column, sort_order);
|
||||
m_sort_column = logicalIndex;
|
||||
}
|
||||
|
||||
void user_manager_dialog::ShowContextMenu(const QPoint &pos)
|
||||
{
|
||||
int idx = m_table->currentRow();
|
||||
if (idx < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
QPoint globalPos = m_table->mapToGlobal(pos);
|
||||
QMenu* menu = new QMenu();
|
||||
|
||||
// Create all the actions before adding them to the menu/submenus.
|
||||
QAction* userIdAct = new QAction(tr("User ID"), this);
|
||||
QAction* userNameAct = new QAction(tr("User Name"), this);
|
||||
|
||||
QAction* removeAct = new QAction(tr("&Remove"), this);
|
||||
QAction* renameAct = new QAction(tr("&Rename"), this);
|
||||
QAction* loginAct = new QAction(tr("&Login"), this);
|
||||
QAction* showDirAct = new QAction(tr("&Open User Directory"), this);
|
||||
|
||||
//Create submenu for sort options.
|
||||
m_sort_options = new QMenu(tr("&Sort By"));
|
||||
m_sort_options->addAction(userIdAct);
|
||||
m_sort_options->addAction(userNameAct);
|
||||
|
||||
// Add all options and submenus to the context menu.
|
||||
menu->addMenu(m_sort_options);
|
||||
menu->addSeparator();
|
||||
menu->addAction(removeAct);
|
||||
menu->addAction(renameAct);
|
||||
menu->addAction(loginAct);
|
||||
menu->addAction(showDirAct);
|
||||
|
||||
// Only enable actions if selected user is not logged in user.
|
||||
int idx_real = m_table->item(idx, 0)->data(Qt::UserRole).toInt();
|
||||
std::string idx_user = m_user_list[idx_real]->GetUserId();
|
||||
bool enable = idx_user != m_selected_user;
|
||||
|
||||
removeAct->setEnabled(enable);
|
||||
renameAct->setEnabled(enable);
|
||||
|
||||
// Connects and Events
|
||||
connect(removeAct, &QAction::triggered, this, &user_manager_dialog::OnUserRemove);
|
||||
connect(renameAct, &QAction::triggered, this, &user_manager_dialog::OnUserRename);
|
||||
connect(loginAct, &QAction::triggered, this, &user_manager_dialog::OnUserLogin);
|
||||
connect(showDirAct, &QAction::triggered, [=]()
|
||||
{
|
||||
int idx_real = m_table->item(idx, 0)->data(Qt::UserRole).toInt();
|
||||
QString path = qstr(m_user_list[idx_real]->GetUserDir());
|
||||
QDesktopServices::openUrl(QUrl("file:///" + path));
|
||||
});
|
||||
|
||||
connect(userIdAct, &QAction::triggered, this, [=] {OnSort(0); });
|
||||
connect(userNameAct, &QAction::triggered, this, [=] {OnSort(1); });
|
||||
|
||||
menu->exec(globalPos);
|
||||
}
|
||||
|
||||
void user_manager_dialog::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
m_gui_settings->SetValue(gui::um_geometry, saveGeometry());
|
||||
QDialog::closeEvent(event);
|
||||
}
|
58
rpcs3/rpcs3qt/user_manager_dialog.h
Normal file
58
rpcs3/rpcs3qt/user_manager_dialog.h
Normal file
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "gui_settings.h"
|
||||
#include "emu_settings.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include "Utilities/File.h"
|
||||
#include "user_account.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QTableWidget>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QHeaderView>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QDesktopWidget>
|
||||
#include <QApplication>
|
||||
#include <QUrl>
|
||||
#include <QDesktopServices>
|
||||
|
||||
class user_manager_dialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit user_manager_dialog(std::shared_ptr<gui_settings> gui_settings, std::shared_ptr<emu_settings> emu_settings, const std::string& dir = "", QWidget* parent = nullptr);
|
||||
Q_SIGNALS:
|
||||
void OnUserLoginSuccess();
|
||||
private Q_SLOTS:
|
||||
void OnUserLogin();
|
||||
void OnUserCreate();
|
||||
void OnUserRemove();
|
||||
void OnUserRename();
|
||||
void OnSort(int logicalIndex);
|
||||
private:
|
||||
void Init(const std::string& dir);
|
||||
void UpdateTable();
|
||||
void GenerateUser(const std::string& username);
|
||||
bool ValidateUsername(const QString& textToValidate);
|
||||
|
||||
void ShowContextMenu(const QPoint &pos);
|
||||
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
|
||||
QTableWidget* m_table;
|
||||
std::string m_dir;
|
||||
std::string m_selected_user;
|
||||
std::vector<UserAccount*> m_user_list;
|
||||
|
||||
std::shared_ptr<gui_settings> m_gui_settings;
|
||||
std::shared_ptr<emu_settings> m_emu_settings;
|
||||
|
||||
QMenu* m_sort_options;
|
||||
|
||||
int m_sort_column;
|
||||
bool m_sort_ascending;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user