Fix bug with app list, adding proc and debug stuff.
This commit is contained in:
@@ -67,7 +67,7 @@ void API::Init()
|
||||
Proc = new class Proc();
|
||||
Apps = new class Apps();
|
||||
Debug = new class Debug();
|
||||
Target = new class Target();
|
||||
Target = new class Target(Debug);
|
||||
Listener = new SocketListener(ListenerCallback, NULL, 6900);
|
||||
Running = true;
|
||||
}
|
||||
|
||||
@@ -146,7 +146,8 @@ struct APIPacket
|
||||
|
||||
struct ProcPacket
|
||||
{
|
||||
int32_t ProcessId;
|
||||
int AppId;
|
||||
int ProcessId;
|
||||
char Name[32];
|
||||
char TitleId[10];
|
||||
};
|
||||
@@ -162,6 +163,28 @@ enum AppState
|
||||
STATE_SUSPENDED,
|
||||
};
|
||||
|
||||
struct AppInfoPacket
|
||||
{
|
||||
char TitleId[10];
|
||||
char ContentId[100];
|
||||
char TitleName[200];
|
||||
char MetaDataPath[100];
|
||||
char LastAccessTime[100];
|
||||
int Visible;
|
||||
int SortPriority;
|
||||
int DispLocation;
|
||||
bool CanRemove;
|
||||
char Category[10];
|
||||
int ContentSize;
|
||||
char InstallDate[100];
|
||||
char UICategory[10];
|
||||
};
|
||||
|
||||
struct AppListPacket
|
||||
{
|
||||
AppInfoPacket Apps[];
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Debug
|
||||
|
||||
@@ -93,14 +93,9 @@ void Apps::GetAppsList(OrbisNetId Sock)
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the number of apps.
|
||||
SockSendInt(Sock, AppList.size());
|
||||
|
||||
// Send all of the apps.
|
||||
for (const auto& App : AppList)
|
||||
{
|
||||
sceNetSend(Sock, &App, sizeof(AppDatabase::AppInfo), 0);
|
||||
}
|
||||
SendLargeData(Sock, (unsigned char*)AppList.data(), AppList.size() * sizeof(AppInfoPacket));
|
||||
}
|
||||
|
||||
void Apps::GetAppInfoString(OrbisNetId Sock, const char* TitleId)
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "Common.h"
|
||||
#include "Debug.h"
|
||||
#include "APIHelper.h"
|
||||
|
||||
#include <sys/ptrace.h>
|
||||
|
||||
void Debug::HandleAPI(OrbisNetId Sock, APIPacket* Packet)
|
||||
{
|
||||
@@ -8,10 +11,83 @@ void Debug::HandleAPI(OrbisNetId Sock, APIPacket* Packet)
|
||||
default:
|
||||
break;
|
||||
|
||||
case API_DBG_ATTACH:
|
||||
|
||||
break;
|
||||
|
||||
case API_DBG_DETACH:
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Debug::TryDetach(int pid)
|
||||
{
|
||||
// Check if we are even attached.
|
||||
if (!IsDebugging)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Detach from the process.
|
||||
int res = ptrace(PT_DETACH, pid, nullptr, 0);
|
||||
if (res != 0)
|
||||
{
|
||||
klog("DetachProcess(): ptrace(PT_DETACH) failed with error %llX\n", res);
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Kill the watching thread and Remove any Watchpoints / Breakpoints now.
|
||||
|
||||
IsDebugging = false;
|
||||
CurrentPID = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Debug::Attach(OrbisNetId Sock)
|
||||
{
|
||||
auto pid = RecieveInt(Sock);
|
||||
|
||||
// If we are currently debugging another process lets detach from it.
|
||||
if (!TryDetach(pid))
|
||||
{
|
||||
klog("Attach(): TryDetach Failed. :(\n");
|
||||
SendStatus(Sock, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Use ptrace to attach to begin debugging this pid.
|
||||
int res = ptrace(PT_ATTACH, pid, nullptr, 0);
|
||||
if (res != 0)
|
||||
{
|
||||
klog("Attach(): ptrace(PT_ATTACH) failed with error %llX\n", res);
|
||||
SendStatus(Sock, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Attaching by default will stop execution of the remote process. Lets continue it now.
|
||||
res = ptrace(PT_CONTINUE, pid, nullptr, 0);
|
||||
if (res != 0)
|
||||
{
|
||||
klog("Attach(): ptrace(PT_CONTINUE) failed with error %llX\n", res);
|
||||
SendStatus(Sock, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
IsDebugging = true;
|
||||
CurrentPID = pid;
|
||||
|
||||
SendStatus(Sock, 1);
|
||||
}
|
||||
|
||||
void Debug::Detach(OrbisNetId Sock)
|
||||
{
|
||||
auto pid = RecieveInt(Sock);
|
||||
auto result = TryDetach(pid);
|
||||
SendStatus(Sock, result ? 1 : 0);
|
||||
}
|
||||
|
||||
Debug::Debug()
|
||||
{
|
||||
|
||||
|
||||
@@ -3,12 +3,16 @@
|
||||
class Debug
|
||||
{
|
||||
public:
|
||||
bool IsDebugging;
|
||||
int CurrentPID;
|
||||
|
||||
Debug();
|
||||
~Debug();
|
||||
void HandleAPI(OrbisNetId Sock, APIPacket* Packet);
|
||||
|
||||
private:
|
||||
bool IsDebugging;
|
||||
int CurrentPID;
|
||||
bool TryDetach(int pid);
|
||||
void Attach(OrbisNetId Sock);
|
||||
void Detach(OrbisNetId Sock);
|
||||
|
||||
};
|
||||
|
||||
@@ -13,8 +13,6 @@ void Proc::HandleAPI(OrbisNetId Sock, APIPacket* Packet)
|
||||
|
||||
SendProcessList(Sock);
|
||||
|
||||
SendStatus(Sock, APIResults::API_OK);
|
||||
|
||||
break;
|
||||
|
||||
case API_PROC_LOAD_ELF:
|
||||
@@ -39,38 +37,31 @@ Proc::~Proc()
|
||||
|
||||
void Proc::SendProcessList(OrbisNetId Sock)
|
||||
{
|
||||
// TODO: Update
|
||||
// Allocate space for packet to send.
|
||||
/*auto Packet = (ProcPacket*)malloc(sizeof(ProcPacket));
|
||||
auto Packet = (ProcPacket*)malloc(sizeof(ProcPacket));
|
||||
|
||||
// Gets list of running processes.
|
||||
auto procInfo = (ProcInfo*)malloc(sizeof(ProcInfo) * 200);
|
||||
memset(procInfo, 0, sizeof(ProcInfo) * 200);
|
||||
int ProcessCount = KDriver::GetProcessList(200, procInfo);
|
||||
// Get the list of running processes.
|
||||
std::vector<kinfo_proc> processList;
|
||||
GetProcessList(processList);
|
||||
|
||||
// Send the number of processes running.
|
||||
sceNetSend(Sock, &ProcessCount, sizeof(int), 0);
|
||||
SockSendInt(Sock, processList.size());
|
||||
|
||||
// Populate each process packet and send it.
|
||||
for (auto i = 0; i < ProcessCount; i++)
|
||||
for (const auto& i : processList)
|
||||
{
|
||||
memset(Packet, 0, sizeof(ProcPacket));
|
||||
|
||||
Packet->ProcessID = procInfo[i].PID;
|
||||
Packet->Attached = procInfo[i].Attached;
|
||||
// Get the app info using the pid.
|
||||
OrbisAppInfo appInfo;
|
||||
sceKernelGetAppInfo(i.pid, &appInfo);
|
||||
|
||||
strcpy(Packet->ProcName, procInfo[i].ProcName);
|
||||
strcpy(Packet->TitleID, procInfo[i].TitleID);
|
||||
|
||||
Packet->TextSegmentBase = procInfo[i].TextSegmentBase;
|
||||
Packet->TextSegmentLen = procInfo[i].TextSegmentLen;
|
||||
Packet->DataSegmentBase = procInfo[i].DataSegmentBase;
|
||||
Packet->DataSegmentLen = procInfo[i].DataSegmentLen;
|
||||
Packet->AppId = appInfo.AppId;
|
||||
Packet->ProcessId = i.pid;
|
||||
strcpy(Packet->Name, i.name);
|
||||
strcpy(Packet->TitleId, appInfo.TitleId);
|
||||
|
||||
sceNetSend(Sock, Packet, sizeof(ProcPacket), 0);
|
||||
}
|
||||
|
||||
// Cleanup.
|
||||
free(Packet);
|
||||
free(procInfo);*/
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "Common.h"
|
||||
#include "Target.h"
|
||||
#include "APIHelper.h"
|
||||
#include "Debug.h"
|
||||
#include <orbis/SysCore.h>
|
||||
|
||||
void Target::HandleAPI(OrbisNetId Sock, APIPacket* Packet)
|
||||
@@ -66,9 +67,9 @@ void Target::HandleAPI(OrbisNetId Sock, APIPacket* Packet)
|
||||
}
|
||||
}
|
||||
|
||||
Target::Target()
|
||||
Target::Target(class Debug* Debug)
|
||||
{
|
||||
|
||||
this->Debug = Debug;
|
||||
}
|
||||
|
||||
Target::~Target()
|
||||
@@ -87,6 +88,7 @@ void Target::SendTargetInfo(OrbisNetId Sock)
|
||||
Packet->CPUTemp = GetCPUTemp();
|
||||
Packet->SOCTemp = GetSOCTemp();
|
||||
|
||||
// Current Big App.
|
||||
auto bigAppAppId = sceSystemServiceGetAppIdOfBigApp();
|
||||
if (bigAppAppId > 0)
|
||||
{
|
||||
@@ -129,11 +131,14 @@ void Target::SendTargetInfo(OrbisNetId Sock)
|
||||
GetPSID(Packet->PSID);
|
||||
Packet->ConsoleType = GetConsoleType();
|
||||
|
||||
// TODO: Debugging Added Later.
|
||||
Packet->Attached = false; // TODO: Add funcionality.
|
||||
//Packet->CurrentProc
|
||||
// Debugging.
|
||||
Packet->AttachedPid = Debug->CurrentPID;
|
||||
Packet->Attached = Debug->IsDebugging;
|
||||
|
||||
// User.
|
||||
sceUserServiceGetForegroundUser(&Packet->ForegroundAccountId);
|
||||
|
||||
// Storage Stats.
|
||||
auto res = ShellCoreUtil::sceShellCoreUtilGetFreeSizeOfUserPartition(&Packet->FreeSpace, &Packet->TotalSpace);
|
||||
|
||||
// Perf Stats. TODO: Move from toolbox
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
class Debug;
|
||||
|
||||
class Target
|
||||
{
|
||||
public:
|
||||
Target();
|
||||
Target(Debug* Debug);
|
||||
~Target();
|
||||
void HandleAPI(OrbisNetId Sock, APIPacket* Packet);
|
||||
|
||||
@@ -12,5 +14,5 @@ public:
|
||||
void SetSettings(OrbisNetId Sock);
|
||||
|
||||
private:
|
||||
|
||||
Debug* Debug;
|
||||
};
|
||||
@@ -202,6 +202,32 @@ bool SockRecvInt(OrbisNetId Sock, int* val)
|
||||
return !(sceNetRecv(Sock, val, sizeof(int), 0) < 0);
|
||||
}
|
||||
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
bool SendLargeData(OrbisNetId Sock, unsigned char* data, size_t dataLen)
|
||||
{
|
||||
unsigned char* CurrentPosition = data;
|
||||
size_t DataLeft = dataLen;
|
||||
int res = 0;
|
||||
|
||||
while (DataLeft > 0)
|
||||
{
|
||||
size_t DataChunkSize = MIN(8192, DataLeft);
|
||||
|
||||
res = sceNetSend(Sock, CurrentPosition, DataChunkSize, 0);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DataLeft -= res;
|
||||
CurrentPosition += res;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
void hexdump(void* ptr, int buflen) {
|
||||
|
||||
@@ -15,9 +15,11 @@ bool Jailbreak();
|
||||
bool CopySflash();
|
||||
int getMacAddress(OrbisNetIfName ifName_Num, char* strOut, size_t strlen);
|
||||
|
||||
//TODO: Make socket class.
|
||||
// Networking
|
||||
bool SockSendInt(OrbisNetId Sock, int val);
|
||||
bool SockRecvInt(OrbisNetId Sock, int* val);
|
||||
bool SendLargeData(OrbisNetId Sock, unsigned char* data, size_t dataLen);
|
||||
|
||||
struct kinfo_proc {
|
||||
int structSize; //0x00
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
#define ORBISLIB_MAJOR 3
|
||||
#define ORBISLIB_MINOR 0
|
||||
#define ORBISLIB_BUILDVERSION 693
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
#if defined(_DEBUG)
|
||||
#define ORBISLIB_BUILDSTRING ("[OrbisLib Daemon " stringify(ORBISLIB_MAJOR) "." stringify(ORBISLIB_MINOR) "] Dev Build " stringify(ORBISLIB_BUILDVERSION) " " __DATE__ " " __TIME__)
|
||||
#else
|
||||
#define ORBISLIB_BUILDSTRING ("[OrbisLib Daemon " stringify(ORBISLIB_MAJOR) "." stringify(ORBISLIB_MINOR) "] Build " stringify(ORBISLIB_BUILDVERSION) " " __DATE__ " " __TIME__)
|
||||
#endif
|
||||
#pragma once
|
||||
#define ORBISLIB_MAJOR 3
|
||||
#define ORBISLIB_MINOR 0
|
||||
#define ORBISLIB_BUILDVERSION 708
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
#if defined(_DEBUG)
|
||||
#define ORBISLIB_BUILDSTRING ("[OrbisLib Daemon " stringify(ORBISLIB_MAJOR) "." stringify(ORBISLIB_MINOR) "] Dev Build " stringify(ORBISLIB_BUILDVERSION) " " __DATE__ " " __TIME__)
|
||||
#else
|
||||
#define ORBISLIB_BUILDSTRING ("[OrbisLib Daemon " stringify(ORBISLIB_MAJOR) "." stringify(ORBISLIB_MINOR) "] Build " stringify(ORBISLIB_BUILDVERSION) " " __DATE__ " " __TIME__)
|
||||
#endif
|
||||
|
||||
@@ -84,7 +84,7 @@ int main()
|
||||
// Init App install utils.
|
||||
sceAppInstUtilInitialize();
|
||||
|
||||
#define LOADTOOLBOX
|
||||
//#define LOADTOOLBOX
|
||||
#ifdef LOADTOOLBOX
|
||||
auto handle = sys_sdk_proc_prx_load("SceShellUI", "/user/data/Orbis Toolbox/OrbisToolbox-2.0.sprx");
|
||||
if (handle > 0) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using OrbisLib2.Common.Helpers;
|
||||
using OrbisLib2.Targets;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OrbisLib2.Common.API
|
||||
{
|
||||
@@ -81,6 +82,34 @@ namespace OrbisLib2.Common.API
|
||||
return (APIResults)Sock.RecvInt32();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recieves the next packet.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The packet type.</typeparam>
|
||||
/// <param name="Sock">Socket to recieve the packet on.</param>
|
||||
/// <param name="Packet">The packet to be recieved on.</param>
|
||||
/// <returns>Returns true if successful.</returns>
|
||||
public static bool RecieveNextPacket<T>(Socket Sock, ref T Packet)
|
||||
{
|
||||
try
|
||||
{
|
||||
var RawPacket = new byte[Marshal.SizeOf(Packet)];
|
||||
var bytes = Sock.Receive(RawPacket);
|
||||
|
||||
if (bytes <= 0)
|
||||
return false;
|
||||
|
||||
// Convert the recieved bytes to a struct.
|
||||
Helper.BytesToStruct(RawPacket, ref Packet);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
||||
@@ -140,11 +140,12 @@ namespace OrbisLib2.Common.API
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Ansi)]
|
||||
public struct ProcPacket
|
||||
{
|
||||
public int ProcessID;
|
||||
public int AppId;
|
||||
public int ProcessId;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||
public string Name;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
|
||||
public string TitleID;
|
||||
public string TitleId;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -159,7 +160,7 @@ namespace OrbisLib2.Common.API
|
||||
STATE_SUSPENDED,
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Ansi), Serializable]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Ansi, Size = 652), Serializable]
|
||||
public struct AppInfoPacket
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Data;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Text;
|
||||
using static SQLite.SQLite3;
|
||||
|
||||
namespace OrbisLib2.Common.Helpers
|
||||
{
|
||||
@@ -89,6 +91,21 @@ namespace OrbisLib2.Common.Helpers
|
||||
return BitConverter.ToInt32(Data, 0);
|
||||
}
|
||||
|
||||
public static void RecvLarge(this Socket s, byte[] data)
|
||||
{
|
||||
int Left = data.Length;
|
||||
int Received = 0;
|
||||
|
||||
while(Left > 0)
|
||||
{
|
||||
var chunkSize = Math.Min(s.ReceiveBufferSize, Left);
|
||||
var res = s.Receive(data, Received, chunkSize, 0);
|
||||
|
||||
Received += res;
|
||||
Left -= res;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easily connect to a socket and handle the time out.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using OrbisLib2.Common.API;
|
||||
using OrbisLib2.Common.Helpers;
|
||||
using System.Data.Entity.Core.Metadata.Edm;
|
||||
using System.Drawing;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
@@ -29,25 +31,25 @@ namespace OrbisLib2.Targets
|
||||
public List<AppInfo> GetAppList()
|
||||
{
|
||||
var AppList = new List<AppInfo>();
|
||||
|
||||
var result = API.SendCommand(Target, 5, APICommands.API_APPS_GET_LIST, (Socket Sock, APIResults Result) =>
|
||||
{
|
||||
// Get the number of apps installed.
|
||||
int Count = Sock.RecvInt32();
|
||||
var Count = Sock.RecvInt32();
|
||||
|
||||
// Itterate through the count to recieve all the apps details.
|
||||
for (int i = 0; i < Count; i++)
|
||||
// Recieve all of the arrary as one large packet.
|
||||
var dataSize = Count * Marshal.SizeOf(typeof(AppInfoPacket));
|
||||
var data = new byte[dataSize];
|
||||
Sock.RecvLarge(data);
|
||||
|
||||
// Allocate and copy the packet to begin marshaling it.
|
||||
IntPtr ptr = Marshal.AllocHGlobal(dataSize);
|
||||
Marshal.Copy(data, 0, ptr, dataSize);
|
||||
|
||||
for(int i = 0; i < Count; i++)
|
||||
{
|
||||
// Recieve the bytes of the struct.
|
||||
// Marshal each part of the buffer to a struct.
|
||||
var Packet = new AppInfoPacket();
|
||||
var RawPacket = new byte[Marshal.SizeOf(Packet)];
|
||||
var bytes = Sock.Receive(RawPacket);
|
||||
|
||||
if (bytes <= 0)
|
||||
break;
|
||||
|
||||
// Convert the recieved bytes to a struct.
|
||||
Helper.BytesToStruct(RawPacket, ref Packet);
|
||||
Packet = (AppInfoPacket)Marshal.PtrToStructure(IntPtr.Add(ptr, i * Marshal.SizeOf(typeof(AppInfoPacket))), typeof(AppInfoPacket));
|
||||
|
||||
// Try to parse the date time strings.
|
||||
if (!DateTime.TryParse(Packet.LastAccessTime, out DateTime LastAccessTime))
|
||||
@@ -60,10 +62,11 @@ namespace OrbisLib2.Targets
|
||||
var firstNullIndex = Array.FindIndex(Packet.TitleName, b => b == 0);
|
||||
string titleName = Encoding.UTF8.GetString(Packet.TitleName, 0, firstNullIndex);
|
||||
|
||||
// Add the entry to the list.
|
||||
AppList.Add(new AppInfo(Packet.TitleId, Packet.ContentId, titleName, Packet.MetaDataPath, LastAccessTime, Packet.Visible,
|
||||
Packet.SortPriority, Packet.DispLocation, Packet.CanRemove == 1, Packet.Category, Packet.ContentSize, InstallDate, Packet.UICategory));
|
||||
}
|
||||
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
});
|
||||
|
||||
return AppList;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
using OrbisLib2.Common.API;
|
||||
using OrbisLib2.Common.Helpers;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OrbisLib2.Targets
|
||||
{
|
||||
public record ProcInfo(int AppId, int ProcessId, string Name, string TitleId);
|
||||
|
||||
public class Process
|
||||
{
|
||||
private Target Target;
|
||||
|
||||
public Process(Target Target)
|
||||
{
|
||||
this.Target = Target;
|
||||
}
|
||||
|
||||
public List<ProcInfo> GetList()
|
||||
{
|
||||
var list = new List<ProcInfo>();
|
||||
|
||||
API.SendCommand(Target, 4, APICommands.API_PROC_GET_LIST, (Socket Sock, APIResults Result) =>
|
||||
{
|
||||
var processCount = Sock.RecvInt32();
|
||||
|
||||
for(int i = 0; i < processCount; i++)
|
||||
{
|
||||
var Packet = new ProcPacket();
|
||||
if(!API.RecieveNextPacket(Sock, ref Packet))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
list.Add(new ProcInfo(Packet.AppId, Packet.ProcessId, Packet.Name, Packet.TitleId));
|
||||
}
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,7 +83,7 @@ namespace OrbisLib2.Targets
|
||||
public TargetEvents Events;
|
||||
// public Debug Debug;
|
||||
public Payload Payload;
|
||||
// public Process Process;
|
||||
public Process Process;
|
||||
public FTP FTP;
|
||||
public Application Application;
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace OrbisLib2.Targets
|
||||
Events = new TargetEvents(this);
|
||||
// Debug = new Debug(this);
|
||||
Payload = new Payload(this);
|
||||
// Process = new Process(PS4, this);
|
||||
Process = new Process(this);
|
||||
FTP = new FTP(this);
|
||||
Application = new Application(this);
|
||||
}
|
||||
|
||||
@@ -46,24 +46,24 @@ namespace OrbisNeighborHood.MVVM.View
|
||||
"CUSA01000"
|
||||
};
|
||||
|
||||
private List<AppPanel> PanelList = new List<AppPanel>();
|
||||
|
||||
public AppListView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Events.DBTouched += Events_DBTouched;
|
||||
Events.TargetStateChanged += Events_TargetStateChanged;
|
||||
// TODO: add event for selected target changing.
|
||||
|
||||
// Refresh the info about the current target.
|
||||
RefreshTargetInfo();
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
// Initially populate the app list.
|
||||
InitAppList();
|
||||
// Set Item source for listbox.
|
||||
AppList.ItemsSource = PanelList;
|
||||
|
||||
// Create task to periodically check for app.db changes.
|
||||
// Task.Run(() => CheckAppDatabase());
|
||||
});
|
||||
// Create task to periodically check for app.db changes.
|
||||
Task.Run(() => CheckAppDatabase());
|
||||
}
|
||||
|
||||
#region Properties
|
||||
@@ -110,95 +110,6 @@ namespace OrbisNeighborHood.MVVM.View
|
||||
|
||||
#endregion
|
||||
|
||||
public void AddApp(string appCachePath, AppInfo App)
|
||||
{
|
||||
var currentTarget = TargetManager.SelectedTarget;
|
||||
|
||||
// Make sure the titleId format is correct. Helps weed out bad entries and folders.
|
||||
if (!Regex.IsMatch(App.TitleId, @"[a-zA-Z]{4}\d{5}"))
|
||||
return;
|
||||
|
||||
// Skip the Destiny entries that just exist for some reason even after a restore?... lol
|
||||
if ((App.TitleId.Equals("CUSA00219") || App.TitleId.Equals("CUSA00568") || App.TitleId.Equals("CUSA01000")) && App.ContentSize <= 0)
|
||||
return;
|
||||
|
||||
// Skip some that aren't technically an app.
|
||||
if (TitleIdExlusionList.Contains(App.TitleId))
|
||||
return;
|
||||
|
||||
// Weed out some more bad entries created by default.
|
||||
if (App.TitleName.Length <= 2)
|
||||
return;
|
||||
|
||||
// Make sure only add ones with a category.
|
||||
if (App.UICategory.Length <= 0 || App.Category.Length <= 0)
|
||||
return;
|
||||
|
||||
// Directory to cache stuff for app.
|
||||
string currentAppPath = Path.Combine(appCachePath, App.TitleId);
|
||||
|
||||
// Create Directory for current app.
|
||||
if (!Directory.Exists(currentAppPath))
|
||||
{
|
||||
Directory.CreateDirectory(currentAppPath);
|
||||
}
|
||||
|
||||
// Cache icon0.png for app if we have not already.
|
||||
if (!File.Exists(Path.Combine(currentAppPath, "icon0.png")) && !string.IsNullOrEmpty(App.MetaDataPath) && currentTarget.Info.IsAvailable) //TODO: Maybe add a isFTPAvailable.
|
||||
{
|
||||
currentTarget.FTP.DownloadFile($"{App.MetaDataPath}/icon0.png", Path.Combine(currentAppPath, "icon0.png"));
|
||||
}
|
||||
|
||||
// Fetch the App version.
|
||||
var appVersion = currentTarget.Application.GetAppInfoString(App.TitleId, "APP_VER");
|
||||
|
||||
// Add or update app list item.
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
var panel = AppList.Items.Cast<AppPanel>().ToList().Find(x => x.App.TitleId == App.TitleId);
|
||||
if (panel != null)
|
||||
{
|
||||
panel.Update(App, appVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
AppList.Items.Add(new AppPanel(App, appVersion));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void InitAppList()
|
||||
{
|
||||
// Clear lists so we can re-populate them.
|
||||
Dispatcher.Invoke(() => AppList.Items.Clear());
|
||||
|
||||
// Make sure we have a target we can pull the db from.
|
||||
if (TargetManager.Targets.Count <= 0)
|
||||
return;
|
||||
|
||||
// Make sure the Target is online so we can pull the db.
|
||||
var currentTarget = TargetManager.SelectedTarget;
|
||||
if (currentTarget == null)
|
||||
{
|
||||
Console.WriteLine("No current target we can use to load apps.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we have the appCache folder.
|
||||
string appCachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), @"Orbis Suite\AppCache\");
|
||||
if (!Directory.Exists(appCachePath))
|
||||
{
|
||||
Directory.CreateDirectory(appCachePath);
|
||||
}
|
||||
|
||||
var appList = currentTarget.Application.GetAppList();
|
||||
|
||||
Parallel.ForEach(appList, app =>
|
||||
{
|
||||
AddApp(appCachePath, app);
|
||||
});
|
||||
}
|
||||
|
||||
private async Task CheckAppDatabase()
|
||||
{
|
||||
while (true)
|
||||
@@ -216,30 +127,81 @@ namespace OrbisNeighborHood.MVVM.View
|
||||
continue;
|
||||
}
|
||||
|
||||
// Appcache location.
|
||||
string appCachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), @"Orbis Suite\AppCache\");
|
||||
|
||||
// Get the current app list.
|
||||
var appList = currentTarget.Application.GetAppList();
|
||||
|
||||
// Check for deletions.
|
||||
Parallel.ForEach(AppList.Items.Cast<AppPanel>().ToList(), app =>
|
||||
// Check for adding apps.
|
||||
Parallel.ForEach(appList, app =>
|
||||
{
|
||||
if (appList.Find(x => x.TitleId == app.App.TitleId) == null)
|
||||
var currentTarget = TargetManager.SelectedTarget;
|
||||
string appCachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), @"Orbis Suite\AppCache\");
|
||||
|
||||
// Make sure the titleId format is correct. Helps weed out bad entries and folders.
|
||||
if (!Regex.IsMatch(app.TitleId, @"[a-zA-Z]{4}\d{5}"))
|
||||
return;
|
||||
|
||||
// Skip the Destiny entries that just exist for some reason even after a restore?... lol
|
||||
if ((app.TitleId.Equals("CUSA00219") || app.TitleId.Equals("CUSA00568") || app.TitleId.Equals("CUSA01000")) && app.ContentSize <= 0)
|
||||
return;
|
||||
|
||||
// Skip some that aren't technically an app.
|
||||
if (TitleIdExlusionList.Contains(app.TitleId))
|
||||
return;
|
||||
|
||||
// Weed out some more bad entries created by default.
|
||||
if (app.TitleName.Length <= 2)
|
||||
return;
|
||||
|
||||
// Make sure only add ones with a category.
|
||||
if (app.UICategory.Length <= 0 || app.Category.Length <= 0)
|
||||
return;
|
||||
|
||||
// Directory to cache stuff for app.
|
||||
string currentAppPath = Path.Combine(appCachePath, app.TitleId);
|
||||
|
||||
// Create Directory for current app.
|
||||
if (!Directory.Exists(currentAppPath))
|
||||
{
|
||||
Dispatcher.Invoke(() => AppList.Items.Remove(app));
|
||||
Directory.CreateDirectory(currentAppPath);
|
||||
}
|
||||
|
||||
// Cache icon0.png for app if we have not already.
|
||||
if (!File.Exists(Path.Combine(currentAppPath, "icon0.png")) && !string.IsNullOrEmpty(app.MetaDataPath) && currentTarget.Info.IsAvailable) //TODO: Maybe add a isFTPAvailable.
|
||||
{
|
||||
currentTarget.FTP.DownloadFile($"{app.MetaDataPath}/icon0.png", Path.Combine(currentAppPath, "icon0.png"));
|
||||
}
|
||||
|
||||
// Fetch the App version.
|
||||
var appVersion = currentTarget.Application.GetAppInfoString(app.TitleId, "APP_VER");
|
||||
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
var pannel = PanelList.Find(x => x.App.TitleId == app.TitleId);
|
||||
if(pannel != null)
|
||||
{
|
||||
pannel.Update(app, appVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
PanelList.Add(new AppPanel(app, appVersion));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Check to remove apps.
|
||||
Parallel.ForEach(PanelList, panel =>
|
||||
{
|
||||
var app = appList.Find(x => x.TitleId == panel.App.TitleId);
|
||||
if(app == null)
|
||||
{
|
||||
PanelList.Remove(panel);
|
||||
}
|
||||
});
|
||||
|
||||
// Check for new apps / updates.
|
||||
Parallel.ForEach(appList, app =>
|
||||
// Update view.
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
var currentAppList = AppList.Items.Cast<AppPanel>().ToList();
|
||||
|
||||
if (currentAppList.Find(x => x.App.TitleId == app.TitleId) == null)
|
||||
{
|
||||
AddApp(appCachePath, app);
|
||||
}
|
||||
AppList.Items.Refresh();
|
||||
});
|
||||
|
||||
await Task.Delay(2000);
|
||||
|
||||
@@ -1 +1 @@
|
||||
2073
|
||||
2161
|
||||
|
||||
@@ -1 +1 @@
|
||||
Version 3.0.2073 Debug Build Friday December 23 2022 11:44 PM
|
||||
Version 3.0.2161 Debug Build Saturday December 24 2022 11:40 AM
|
||||
|
||||
Reference in New Issue
Block a user