1207 lines
42 KiB
C++
1207 lines
42 KiB
C++
|
|
#include "jrpcpp.h"
|
||
|
|
#include "qvariant.h"
|
||
|
|
|
||
|
|
JRPCpp::JRPCpp() {}
|
||
|
|
|
||
|
|
QString JRPCpp::ToHexString(const QString &aString)
|
||
|
|
{
|
||
|
|
return aString.toUtf8().toHex();
|
||
|
|
}
|
||
|
|
|
||
|
|
QByteArray JRPCpp::Push(QByteArray aInArray, char aValue)
|
||
|
|
{
|
||
|
|
QByteArray aOutArray = aInArray;
|
||
|
|
aOutArray.push_back(aValue);
|
||
|
|
return aOutArray;
|
||
|
|
}
|
||
|
|
|
||
|
|
QByteArray JRPCpp::ToByteArray(const QString &aString)
|
||
|
|
{
|
||
|
|
return aString.toUtf8();
|
||
|
|
}
|
||
|
|
|
||
|
|
bool JRPCpp::Connect(const IXboxConsole &aConsole, QString aXboxNameOrIP)
|
||
|
|
{
|
||
|
|
IXboxConsole* newCon = nullptr;
|
||
|
|
if (aXboxNameOrIP == "default")
|
||
|
|
aXboxNameOrIP = XboxManager::DefaultConsole;
|
||
|
|
newCon = new XboxManager().OpenConsole(aXboxNameOrIP);
|
||
|
|
bool Connected = false;
|
||
|
|
while (!Connected)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
connectionId = newCon->OpenConnection(null);
|
||
|
|
Connected = true;
|
||
|
|
}
|
||
|
|
catch (std::exception ex)
|
||
|
|
{
|
||
|
|
if (ex.ErrorCode == UIntToInt(0x82DA0100))
|
||
|
|
{
|
||
|
|
Console = newCon;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
Console = newCon;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
QString JRPCpp::XboxIP(const IXboxConsole &aConsole)
|
||
|
|
{
|
||
|
|
QByteArray address = BitConverter.GetBytes(aConsole.IPAddress);
|
||
|
|
std::reverse(address.constBegin(), address.constEnd());
|
||
|
|
|
||
|
|
return QString::fromUtf8(address);
|
||
|
|
}
|
||
|
|
|
||
|
|
ulong JRPCpp::ConvertToUInt64(QVariant aVariant)
|
||
|
|
{
|
||
|
|
if (aVariant.canConvert(QMetaType::fromType<bool>()))
|
||
|
|
return (ulong)aVariant.value<bool>();
|
||
|
|
else if (aVariant.canConvert(QMetaType::fromType<byte>()))
|
||
|
|
return (ulong)aVariant.value<byte>();
|
||
|
|
else if (aVariant.canConvert(QMetaType::fromType<short>()))
|
||
|
|
return (ulong)aVariant.value<short>();
|
||
|
|
else if (aVariant.canConvert(QMetaType::fromType<int>()))
|
||
|
|
return (ulong)aVariant.value<int>();
|
||
|
|
else if (aVariant.canConvert(QMetaType::fromType<long>()))
|
||
|
|
return (ulong)aVariant.value<long>();
|
||
|
|
else if (aVariant.canConvert(QMetaType::fromType<ushort>()))
|
||
|
|
return (ulong)aVariant.value<ushort>();
|
||
|
|
else if (aVariant.canConvert(QMetaType::fromType<uint>()))
|
||
|
|
return (ulong)aVariant.value<uint>();
|
||
|
|
else if (aVariant.canConvert(QMetaType::fromType<ulong>()))
|
||
|
|
return (ulong)aVariant.value<ulong>();
|
||
|
|
else if (aVariant.canConvert(QMetaType::fromType<float>()))
|
||
|
|
return (ulong)aVariant.value<float>();
|
||
|
|
else if (aVariant.canConvert(QMetaType::fromType<double>()))
|
||
|
|
return (ulong)aVariant.value<double>();
|
||
|
|
return 0UL;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool JRPCpp::isNumericPrimitive(QMetaType t)
|
||
|
|
{
|
||
|
|
switch (t.id()) {
|
||
|
|
case QMetaType::Bool:
|
||
|
|
case QMetaType::Char:
|
||
|
|
case QMetaType::SChar:
|
||
|
|
case QMetaType::UChar:
|
||
|
|
case QMetaType::Short:
|
||
|
|
case QMetaType::UShort:
|
||
|
|
case QMetaType::Int:
|
||
|
|
case QMetaType::UInt:
|
||
|
|
case QMetaType::LongLong:
|
||
|
|
case QMetaType::ULongLong:
|
||
|
|
case QMetaType::Float:
|
||
|
|
case QMetaType::Double:
|
||
|
|
return true;
|
||
|
|
default:
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
bool JRPCpp::IsValidStructType(QMetaType t)
|
||
|
|
{
|
||
|
|
return isNumericPrimitive(t);
|
||
|
|
}
|
||
|
|
|
||
|
|
bool JRPCpp::IsValidReturnType(QMetaType t)
|
||
|
|
{
|
||
|
|
return ValidReturnTypes.contains(t);
|
||
|
|
}
|
||
|
|
|
||
|
|
QByteArray JRPCpp::GetMemory(const IXboxConsole &aConsole, uint aAddress, uint aLength)
|
||
|
|
{
|
||
|
|
QByteArray result(aLength, Qt::Uninitialized);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
uint Out = 0;
|
||
|
|
aConsole.DebugTarget.GetMemory(Address, Length, Return, out Out);
|
||
|
|
aConsole.DebugTarget.InvalidateMemoryCache(true, aAddress, Length);
|
||
|
|
return Return;
|
||
|
|
}
|
||
|
|
|
||
|
|
byte JRPCpp::ReadSByte(const IXboxConsole &aConsole, uint aAddress)
|
||
|
|
{
|
||
|
|
return (byte)GetMemory(aConsole, aAddress, 1)[0];
|
||
|
|
}
|
||
|
|
|
||
|
|
byte JRPCpp::ReadByte(const IXboxConsole &aConsole, uint aAddress)
|
||
|
|
{
|
||
|
|
return GetMemory(aConsole, aAddress, 1)[0];
|
||
|
|
}
|
||
|
|
|
||
|
|
bool JRPCpp::ReadBool(const IXboxConsole &aConsole, uint aAddress)
|
||
|
|
{
|
||
|
|
return GetMemory(aConsole, aAddress, 1)[0] != 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
QVector<qint64> JRPCpp::ReadInt64(const IXboxConsole &aConsole, uint aAddress, uint aArraySize)
|
||
|
|
{
|
||
|
|
QVector<qint64> result(aArraySize);
|
||
|
|
|
||
|
|
QByteArray buff = GetMemory(aConsole, aAddress, aArraySize * 8);
|
||
|
|
ReverseBytes(buff, 8);
|
||
|
|
for (int i = 0; i < aArraySize; i++)
|
||
|
|
{
|
||
|
|
QByteArray intBuff = buff.mid(i * 8, 8);
|
||
|
|
result[i] = intBuff.toInt();
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteBool(const IXboxConsole &aConsole, uint aAddress, QVector<bool> aValue)
|
||
|
|
{
|
||
|
|
QByteArray result;
|
||
|
|
for(int i = 0; i < aValue.size(); i++)
|
||
|
|
{
|
||
|
|
result.push_back((char)(aValue[i] ? 1 : 0));
|
||
|
|
}
|
||
|
|
SetMemory(aConsole, aAddress, result);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteFloat(const IXboxConsole &aConsole, uint aAddress, float aValue)
|
||
|
|
{
|
||
|
|
QByteArray buff = QString::number(aValue).toUtf8();
|
||
|
|
Array.Reverse(buff);
|
||
|
|
SetMemory(aConsole, aAddress, buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteFloat(const IXboxConsole &aConsole, uint aAddress, QVector<float> aValue)
|
||
|
|
{
|
||
|
|
QByteArray buff(aValue.size() * 4);
|
||
|
|
for (int i = 0; i < aValue.size(); i++)
|
||
|
|
{
|
||
|
|
BitConverter.GetBytes(aValue[i]).CopyTo(buff, i * 4);
|
||
|
|
}
|
||
|
|
ReverseBytes(buff, 4);
|
||
|
|
SetMemory(aConsole, aAddress, buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteInt16(const IXboxConsole &aConsole, uint aAddress, short aValue)
|
||
|
|
{
|
||
|
|
QByteArray Buff = BitConverter.GetBytes(Value);
|
||
|
|
ReverseBytes(Buff, 2);
|
||
|
|
SetMemory(aConsole, aAddress, Buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteInt16(const IXboxConsole &aConsole, uint aAddress, QVector<short> aValue)
|
||
|
|
{
|
||
|
|
QByteArray Buff = new byte[Value.Length * 2];
|
||
|
|
for (int i = 0; i < aValue.Length; i++)
|
||
|
|
BitConverter.GetBytes(Value[i]).CopyTo(Buff, i * 2);
|
||
|
|
ReverseBytes(Buff, 2);
|
||
|
|
SetMemory(aConsole, aAddress, Buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteUInt16(const IXboxConsole &aConsole, uint aAddress, ushort aValue)
|
||
|
|
{
|
||
|
|
QByteArray Buff = BitConverter.GetBytes(Value);
|
||
|
|
ReverseBytes(Buff, 2);
|
||
|
|
SetMemory(aConsole, aAddress, Buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteUInt16(const IXboxConsole &aConsole, uint aAddress, QVector<short> aValue)
|
||
|
|
{
|
||
|
|
QByteArray Buff = new byte[Value.Length * 2];
|
||
|
|
for (int i = 0; i < aValue.Length; i++)
|
||
|
|
BitConverter.GetBytes(Value[i]).CopyTo(Buff, i * 2);
|
||
|
|
ReverseBytes(Buff, 2);
|
||
|
|
SetMemory(aConsole, aAddress, Buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteInt32(const IXboxConsole &aConsole, uint aAddress, int aValue)
|
||
|
|
{
|
||
|
|
QByteArray Buff = BitConverter.GetBytes(Value);
|
||
|
|
ReverseBytes(Buff, 4);
|
||
|
|
SetMemory(aConsole, aAddress, Buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteInt32(const IXboxConsole &aConsole, uint aAddress, QVector<int> aValue)
|
||
|
|
{
|
||
|
|
QByteArray Buff = new byte[Value.Length * 4];
|
||
|
|
for (int i = 0; i < aValue.Length; i++)
|
||
|
|
BitConverter.GetBytes(Value[i]).CopyTo(Buff, i * 4);
|
||
|
|
ReverseBytes(Buff, 4);
|
||
|
|
SetMemory(aConsole, aAddress, Buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteUInt32(const IXboxConsole &aConsole, uint aAddress, uint aValue)
|
||
|
|
{
|
||
|
|
QByteArray Buff = BitConverter.GetBytes(Value);
|
||
|
|
ReverseBytes(Buff, 4);
|
||
|
|
SetMemory(aConsole, aAddress, Buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteUInt32(const IXboxConsole &aConsole, uint aAddress, QVector<uint> aValue)
|
||
|
|
{
|
||
|
|
QByteArray Buff = new byte[Value.Length * 4];
|
||
|
|
for (int i = 0; i < aValue.Length; i++)
|
||
|
|
BitConverter.GetBytes(Value[i]).CopyTo(Buff, i * 4);
|
||
|
|
ReverseBytes(Buff, 4);
|
||
|
|
SetMemory(aConsole, aAddress, Buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteInt64(const IXboxConsole &aConsole, uint aAddress, long aValue)
|
||
|
|
{
|
||
|
|
QByteArray Buff = BitConverter.GetBytes(Value);
|
||
|
|
ReverseBytes(Buff, 8);
|
||
|
|
SetMemory(aConsole, aAddress, Buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteInt64(const IXboxConsole &aConsole, uint aAddress, QVector<long> aValue)
|
||
|
|
{
|
||
|
|
QByteArray Buff = new byte[Value.Length * 8];
|
||
|
|
for (int i = 0; i < aValue.Length; i++)
|
||
|
|
BitConverter.GetBytes(Value[i]).CopyTo(Buff, i * 8);
|
||
|
|
ReverseBytes(Buff, 8);
|
||
|
|
SetMemory(aConsole, aAddress, Buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteUInt64(const IXboxConsole &aConsole, uint aAddress, unsigned long aValue)
|
||
|
|
{
|
||
|
|
QByteArray Buff = BitConverter.GetBytes(Value);
|
||
|
|
ReverseBytes(Buff, 8);
|
||
|
|
SetMemory(aConsole, aAddress, Buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteUInt64(const IXboxConsole &aConsole, uint aAddress, QVector<unsigned long> aValue)
|
||
|
|
{
|
||
|
|
QByteArray Buff = new byte[Value.Length * 8];
|
||
|
|
for (int i = 0; i < aValue.Length; i++)
|
||
|
|
BitConverter.GetBytes(Value[i]).CopyTo(Buff, i * 8);
|
||
|
|
ReverseBytes(Buff, 8);
|
||
|
|
SetMemory(aConsole, aAddress, Buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteString(const IXboxConsole &aConsole, uint aAddress, QString String)
|
||
|
|
{
|
||
|
|
QByteArray bValue = new byte[0];
|
||
|
|
foreach(byte b in String)
|
||
|
|
bValue.Push(out bValue, b);
|
||
|
|
bValue.Push(out bValue, 0);
|
||
|
|
SetMemory(aConsole, aAddress, bValue);
|
||
|
|
}
|
||
|
|
|
||
|
|
uint JRPCpp::ResolveFunction(const IXboxConsole &aConsole, QString aModuleName, uint aOrdinal)
|
||
|
|
{
|
||
|
|
QString cmd = "consolefeatures ver=" + JRPCVersion + " type=9 params=\"A\\0\\A\\2\\" +
|
||
|
|
JRPC.String + "/" + ModuleName.Length + "\\" + ModuleName.ToHexString() + "\\" +
|
||
|
|
JRPC.Int + "\\" + aOrdinal + "\\\"",
|
||
|
|
Responce = SendCommand(aConsole, cmd);
|
||
|
|
return uint.Parse(Responce.SubQString(Responce.find(" ")+1), System.Globalization.NumberStyles.HexNumber);
|
||
|
|
}
|
||
|
|
|
||
|
|
QString JRPCpp::GetCPUKey(const IXboxConsole &aConsole)
|
||
|
|
{
|
||
|
|
QString cmd = QString("consolefeatures ver=%1 type=10 params=\"A\\0\\A\\0\\\"").arg(JRPCVersion);
|
||
|
|
QString response = SendCommand(aConsole, cmd);
|
||
|
|
return response.mid(response.indexOf(" ") + 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::ShutDownConsole(const IXboxConsole &aConsole)
|
||
|
|
{
|
||
|
|
QString cmd = QString("consolefeatures ver=%1 type=11 params=\"A\\0\\A\\0\\\"").arg(JRPCVersion);
|
||
|
|
SendCommand(aConsole, cmd);
|
||
|
|
}
|
||
|
|
|
||
|
|
QByteArray JRPCpp::WCHAR(QString String)
|
||
|
|
{
|
||
|
|
QByteArray Bytes = new byte[String.Length * 2 + 2];
|
||
|
|
int i = 1;
|
||
|
|
foreach (byte b in String)
|
||
|
|
{
|
||
|
|
Bytes[i] = b;
|
||
|
|
i += 2;
|
||
|
|
}
|
||
|
|
return Bytes;
|
||
|
|
}
|
||
|
|
|
||
|
|
QByteArray JRPCpp::ToWCHAR(QString String)
|
||
|
|
{
|
||
|
|
return WCHAR(String);
|
||
|
|
}
|
||
|
|
|
||
|
|
uint JRPCpp::GetKernalVersion(const IXboxConsole &aConsole)
|
||
|
|
{
|
||
|
|
QString cmd = QString("consolefeatures ver=%1 type=13 params=\"A\\0\\A\\0\\\"").arg(JRPCVersion);
|
||
|
|
QString response = SendCommand(aConsole, cmd);
|
||
|
|
|
||
|
|
bool ok;
|
||
|
|
QString uintStr = response.mid(response.indexOf(" ") + 1);
|
||
|
|
uint result = uintStr.toUInt(&ok);
|
||
|
|
if (!ok)
|
||
|
|
{
|
||
|
|
qDebug() << "ERROR: Failed to convert to UInt str" << uintStr;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::SetLeds(const IXboxConsole &aConsole, LEDState aTopLeft, LEDState aTopRight, LEDState aBottomLeft, LEDState aBottomRight)
|
||
|
|
{
|
||
|
|
QString cmd = QString("consolefeatures ver=%1 type=14 params=\"A\\0\\A\\4\\%2\\%3\\%2\\%4\\%2\\%5\\%2\\%6\\\"")
|
||
|
|
.arg(JRPCVersion)
|
||
|
|
.arg(JRPCpp::Int)
|
||
|
|
.arg(aTopLeft)
|
||
|
|
.arg(aTopRight)
|
||
|
|
.arg(aBottomLeft)
|
||
|
|
.arg(aBottomRight);
|
||
|
|
SendCommand(aConsole, cmd);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::XNotify(const IXboxConsole &aConsole, QString aText)
|
||
|
|
{
|
||
|
|
XNotify(aConsole, XNotifyLogo::FLASHING_XBOX_CONSOLE, aText);
|
||
|
|
}
|
||
|
|
|
||
|
|
uint JRPCpp::GetTemperature(const IXboxConsole &aConsole, TemperatureType TemperatureType)
|
||
|
|
{
|
||
|
|
QString cmd = QString("consolefeatures ver=%1 type=15 params=\"A\\0\\A\\1\\%2\\%3\\\"")
|
||
|
|
.arg(JRPCVersion)
|
||
|
|
.arg(JRPCpp::Int)
|
||
|
|
.arg(TemperatureType);
|
||
|
|
|
||
|
|
QString response = SendCommand(aConsole, cmd);
|
||
|
|
|
||
|
|
bool ok;
|
||
|
|
QString uintStr = response.mid(response.indexOf(" ") + 1);
|
||
|
|
uint result = uintStr.toUInt(&ok);
|
||
|
|
if (!ok)
|
||
|
|
{
|
||
|
|
qDebug() << "ERROR: Failed to convert to UInt str" << uintStr;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::XNotify(const IXboxConsole &aConsole, XNotifyLogo aType, QString aText)
|
||
|
|
{
|
||
|
|
QString cmd = QString("consolefeatures ver=%1 type=12 params=\"A\\0\\A\\2\\%2\\%3\\\"")
|
||
|
|
.arg(JRPCVersion)
|
||
|
|
.arg(JRPCpp::String)
|
||
|
|
.arg(aText.length())
|
||
|
|
.arg(aText.toUtf8().toHex())
|
||
|
|
.arg(aType);
|
||
|
|
|
||
|
|
SendCommand(aConsole, cmd);
|
||
|
|
}
|
||
|
|
|
||
|
|
uint JRPCpp::XamGetCurrentTitleId(const IXboxConsole &aConsole)
|
||
|
|
{
|
||
|
|
QString cmd = QString("consolefeatures ver=%1 type=16 params=\"A\\0\\A\\0\\\"").arg(JRPCVersion);
|
||
|
|
QString response = SendCommand(aConsole, cmd);
|
||
|
|
|
||
|
|
bool ok;
|
||
|
|
QString uintStr = response.mid(response.indexOf(" ") + 1);
|
||
|
|
uint result = uintStr.toUInt(&ok);
|
||
|
|
if (!ok)
|
||
|
|
{
|
||
|
|
qDebug() << "ERROR: Failed to convert to UInt str" << uintStr;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
QString JRPCpp::ConsoleType(const IXboxConsole &aConsole)
|
||
|
|
{
|
||
|
|
QString cmd = QString("consolefeatures ver=%1 type=17 params=\"A\\0\\A\\0\\\"")
|
||
|
|
.arg(JRPCVersion);
|
||
|
|
|
||
|
|
QString response = SendCommand(aConsole, cmd);
|
||
|
|
return response.mid(response.indexOf(" ") + 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::constantMemorySet(const IXboxConsole &aConsole, uint aAddress, uint aValue)
|
||
|
|
{
|
||
|
|
constantMemorySetting(aConsole, aAddress, aValue, false, 0, false, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::constantMemorySet(const IXboxConsole &aConsole, uint aAddress, uint aValue, uint TitleID)
|
||
|
|
{
|
||
|
|
constantMemorySetting(aConsole, aAddress, aValue, false, 0, true, TitleID);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::constantMemorySet(const IXboxConsole &aConsole, uint aAddress, uint aValue, uint IfValue, uint TitleID)
|
||
|
|
{
|
||
|
|
constantMemorySetting(aConsole, aAddress, aValue, true, IfValue, true, TitleID);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::constantMemorySetting(
|
||
|
|
const IXboxConsole& aConsole,
|
||
|
|
uint aAddress,
|
||
|
|
uint aValue,
|
||
|
|
bool useIfValue,
|
||
|
|
uint IfValue,
|
||
|
|
bool usetitleID,
|
||
|
|
uint TitleID)
|
||
|
|
{
|
||
|
|
QString cmd = QString("consolefeatures ver=%1 type=18 params=\"A\\%2\\A\\5\\\"%3\\%4\\%3\\%5\\%3\\%6\\%3\\%7\\%3\\%8\\\"")
|
||
|
|
.arg(JRPCVersion)
|
||
|
|
.arg(aAddress)
|
||
|
|
.arg(JRPCpp::Int)
|
||
|
|
.arg(UIntToInt(aValue))
|
||
|
|
.arg((useIfValue ? 1 : 0))
|
||
|
|
.arg(IfValue)
|
||
|
|
.arg((usetitleID ? 1 : 0))
|
||
|
|
.arg(UIntToInt(TitleID));
|
||
|
|
SendCommand(aConsole, cmd);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::CallVoid(const IXboxConsole &aConsole, uint aAddress, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
CallArgs(aConsole, true, JRPCpp::Void, QMetaType::fromType<void>(), nullptr, 0, aAddress, 0, false, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::CallVoid(const IXboxConsole &aConsole, QString aModule, int aOrdinal, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
CallArgs(aConsole, true, JRPCpp::Void, QMetaType::fromType<void>(), aModule, aOrdinal, 0, 0, false, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::CallVoid(const IXboxConsole &aConsole, ThreadType aType, uint aAddress, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
CallArgs(aConsole, aType == ThreadType::SystemType, JRPCpp::Void, QMetaType::fromType<void>(), nullptr, 0, aAddress, 0, false, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::CallVoid(const IXboxConsole &aConsole, ThreadType aType, QString aModule, int aOrdinal, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
CallArgs(aConsole, aType == ThreadType::SystemType, JRPCpp::Void, QMetaType::fromType<void>(), aModule, aOrdinal, 0, 0, false, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename T>
|
||
|
|
QVector<T> JRPCpp::ArrayReturn(const IXboxConsole &aConsole, uint aAddress, uint Size)
|
||
|
|
{
|
||
|
|
if(Size == 0)
|
||
|
|
return new T[1];
|
||
|
|
QMetaType type = QMetaType::fromType<T>();
|
||
|
|
QVariant result;
|
||
|
|
|
||
|
|
if (type == QMetaType::fromType<short>())
|
||
|
|
result.fromValue(ReadInt16(aConsole, aAddress, Size));
|
||
|
|
if (type == QMetaType::fromType<ushort>())
|
||
|
|
result.fromValue(ReadUInt16(aConsole, aAddress, Size));
|
||
|
|
if (type == QMetaType::fromType<int>())
|
||
|
|
result.fromValue(ReadInt32(aConsole, aAddress, Size));
|
||
|
|
if (type == QMetaType::fromType<uint>())
|
||
|
|
result.fromValue(ReadUInt32(aConsole, aAddress, Size));
|
||
|
|
if (type == QMetaType::fromType<long>())
|
||
|
|
result.fromValue(ReadInt64(aConsole, aAddress, Size));
|
||
|
|
if (type == QMetaType::fromType<ulong>())
|
||
|
|
result.fromValue(ReadUInt64(aConsole, aAddress, Size));
|
||
|
|
if (type == QMetaType::fromType<float>())
|
||
|
|
result.fromValue(ReadFloat(aConsole, aAddress, Size));
|
||
|
|
if (type == QMetaType::fromType<byte>())
|
||
|
|
result.fromValue(GetMemory(aConsole, aAddress, Size));
|
||
|
|
return (T[])result;
|
||
|
|
}
|
||
|
|
|
||
|
|
QString JRPCpp::CallString(const IXboxConsole &aConsole, uint aAddress, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return CallArgs(aConsole, true, JRPCpp::String, QMetaType::fromType<QString>(), nullptr, 0, aAddress, 0, false, aArguments)
|
||
|
|
.toString();
|
||
|
|
}
|
||
|
|
|
||
|
|
QString JRPCpp::CallString(const IXboxConsole &aConsole, QString aModule, int aOrdinal, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return CallArgs(aConsole, true, JRPCpp::String, QMetaType::fromType<QString>(), aModule, aOrdinal, 0, 0, false, aArguments)
|
||
|
|
.toString();
|
||
|
|
}
|
||
|
|
|
||
|
|
QString JRPCpp::CallString(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return CallArgs(aConsole, Type == ThreadType::SystemType, JRPCpp::String, QMetaType::fromType<QString>(), nullptr, 0, aAddress, 0, false, aArguments)
|
||
|
|
.toString();
|
||
|
|
}
|
||
|
|
|
||
|
|
QString JRPCpp::CallString(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return CallArgs(aConsole, Type == ThreadType::SystemType, JRPCpp::String, QMetaType::fromType<QString>(), aModule, aOrdinal, 0, 0, false, aArguments)
|
||
|
|
.toString();
|
||
|
|
}
|
||
|
|
|
||
|
|
int JRPCpp::UIntToInt(uint aValue)
|
||
|
|
{
|
||
|
|
QByteArray array = BitConverter.GetBytes(Value);
|
||
|
|
return BitConverter.ToInt32(array, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
QByteArray JRPCpp::IntArrayToByte(QVector<int> iArray)
|
||
|
|
{
|
||
|
|
QByteArray Bytes = new byte[iArray.Length * 4];
|
||
|
|
for (int i = 0, q = 0; i < iArray.Length; i++, q += 4)
|
||
|
|
for (int w = 0; w < 4; w++)
|
||
|
|
Bytes[q + w] = BitConverter.GetBytes(iArray[i])[w];
|
||
|
|
return Bytes;
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::CallVMVoid(const IXboxConsole &aConsole, uint aAddress, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
CallArgs(aConsole, true, JRPCpp::Void, QMetaType::fromType<void>(), nullptr, 0, aAddress, 0, true, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::CallVMVoid(const IXboxConsole &aConsole, QString aModule, int aOrdinal, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
CallArgs(aConsole, true, JRPCpp::Void, QMetaType::fromType<void>(), aModule, aOrdinal, 0, 0, true, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::CallVMVoid(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
CallArgs(aConsole, Type == ThreadType::SystemType, JRPCpp::Void, QMetaType::fromType<void>(), nullptr, 0, aAddress, 0, true, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::CallVMVoid(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
CallArgs(aConsole, Type == ThreadType::SystemType, JRPCpp::Void, QMetaType::fromType<void>(), aModule, aOrdinal, 0, 0, true, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename T>
|
||
|
|
QVector<T> CallVMArray(const IXboxConsole &aConsole, uint aAddress, uint aArraySize, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
if (aArraySize == 0)
|
||
|
|
return new T[1];
|
||
|
|
return (T[])CallArgs(aConsole, true, TypeToType(true), QMetaType::fromType<T>(), nullptr, 0, aAddress, aArraySize, true, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename T>
|
||
|
|
QVector<T> CallVMArray(const IXboxConsole &aConsole, QString aModule, int aOrdinal, uint aArraySize, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
if (aArraySize == 0)
|
||
|
|
return new T[1];
|
||
|
|
return (T[])CallArgs(aConsole, true, TypeToType(true), QMetaType::fromType<T>(), aModule, aOrdinal, 0, aArraySize, true, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename T>
|
||
|
|
QVector<T> CallVMArray(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, uint aArraySize, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
if (aArraySize == 0)
|
||
|
|
return new T[1];
|
||
|
|
return (T[])CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(true), QMetaType::fromType<T>(), nullptr, 0, aAddress, aArraySize, true, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename T>
|
||
|
|
QVector<T> CallVMArray(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, uint aArraySize, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
if (aArraySize == 0)
|
||
|
|
return new T[1];
|
||
|
|
return (T[])CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(true), QMetaType::fromType<T>(), aModule, aOrdinal, 0, aArraySize, true, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
QString JRPCpp::CallVMString(const IXboxConsole &aConsole, uint aAddress, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return CallArgs(aConsole, true, JRPCpp::String, QMetaType::fromType<QString>(), nullptr, 0, aAddress, 0, true, aArguments).toString();
|
||
|
|
}
|
||
|
|
|
||
|
|
QString JRPCpp::CallVMString(const IXboxConsole &aConsole, QString aModule, int aOrdinal, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return CallArgs(aConsole, true, JRPCpp::String, QMetaType::fromType<QString>(), aModule, aOrdinal, 0, 0, true, aArguments).toString();
|
||
|
|
}
|
||
|
|
|
||
|
|
QString JRPCpp::CallVMString(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return CallArgs(aConsole, Type == ThreadType::SystemType, JRPCpp::String, QMetaType::fromType<QString>(), nullptr, 0, aAddress, 0, true, aArguments)
|
||
|
|
.toString();
|
||
|
|
}
|
||
|
|
|
||
|
|
QString JRPCpp::CallVMString(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return CallArgs(aConsole, Type == ThreadType::SystemType, JRPCpp::String, QMetaType::fromType<QString>(), aModule, aOrdinal, 0, 0, true, aArguments)
|
||
|
|
.toString();
|
||
|
|
}
|
||
|
|
|
||
|
|
QString JRPCpp::SendCommand(const IXboxConsole &aConsole, QString Command)
|
||
|
|
{
|
||
|
|
QString response;
|
||
|
|
if (connectionId == 0)
|
||
|
|
throw std::exception("IXboxConsole argument did not connect using JRPC's connect function.");
|
||
|
|
try
|
||
|
|
{
|
||
|
|
aConsole.SendTextCommand(connectionId, Command, out Responce);
|
||
|
|
if (response.contains("error="))
|
||
|
|
{
|
||
|
|
//throw std::exception(response.mid(11));
|
||
|
|
}
|
||
|
|
if (response.contains("DEBUG"))
|
||
|
|
{
|
||
|
|
throw std::exception("JRPC is not installed on the current console");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (COMException ex)
|
||
|
|
{
|
||
|
|
// if (ex.ErrorCode == UIntToInt(0x82DA0007))
|
||
|
|
// throw std::exception("JRPC is not installed on the current console");
|
||
|
|
// else
|
||
|
|
throw ex;
|
||
|
|
}
|
||
|
|
return response;
|
||
|
|
}
|
||
|
|
|
||
|
|
QVariant JRPCpp::CallArgs(const IXboxConsole &aConsole, bool aSystemThread, uint aType, QMetaType t, QString aModule, int aOrdinal, uint aAddress, uint aArraySize, bool VM, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
if (!JRPCpp::IsValidReturnType(t))
|
||
|
|
{
|
||
|
|
qDebug() << "ERROR: Invalid type " << t.name() << "\nJRPC only supports: bool, byte, short, int, long, ushort, uint, unsigned long, float, double";
|
||
|
|
return QVariant();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
aConsole.ConnectTimeout = aConsole.ConversationTimeout = 4000000;//set to 400 secounds incase there is a little delay in recving
|
||
|
|
QString SendCMD = "";
|
||
|
|
uint NumOfArgs = 0;
|
||
|
|
foreach (QVariant obj, aArguments)
|
||
|
|
{
|
||
|
|
bool Done = false;
|
||
|
|
if (obj.canConvert(QMetaType::fromType<uint>()))
|
||
|
|
{
|
||
|
|
SendCMD += QString("%1\\%2\\")
|
||
|
|
.arg(JRPCpp::Int)
|
||
|
|
.arg(obj.value<uint>());
|
||
|
|
NumOfArgs += 1;
|
||
|
|
Done = true;
|
||
|
|
}
|
||
|
|
if (obj.canConvert(QMetaType::fromType<int>())
|
||
|
|
|| obj.canConvert(QMetaType::fromType<bool>())
|
||
|
|
|| obj.canConvert(QMetaType::fromType<byte>()))
|
||
|
|
{
|
||
|
|
if (obj.canConvert(QMetaType::fromType<byte>()))
|
||
|
|
{
|
||
|
|
SendCMD += QString("%1\\%2\\")
|
||
|
|
.arg(JRPCpp::Int)
|
||
|
|
.arg(obj.value<byte>());
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
SendCMD += QString("%1\\%2\\")
|
||
|
|
.arg(JRPCpp::Int)
|
||
|
|
.arg(obj.value<qint32>());
|
||
|
|
}
|
||
|
|
NumOfArgs += 1;
|
||
|
|
Done = true;
|
||
|
|
}
|
||
|
|
else if (obj.canConvert(QMetaType::fromType<QVector<int>>())
|
||
|
|
|| obj.canConvert(QMetaType::fromType<QVector<uint>>()))
|
||
|
|
{
|
||
|
|
if (!VM)
|
||
|
|
{
|
||
|
|
QByteArray array = IntArrayToByte(obj.value<QVector<int>>());
|
||
|
|
SendCMD += QString("%1/%2\\").arg(JRPCpp::ByteArray).arg(array.size());
|
||
|
|
for (int i = 0; i < array.size(); i++)
|
||
|
|
SendCMD += QString::number(array[i]);
|
||
|
|
SendCMD += "\\";
|
||
|
|
NumOfArgs += 1;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
bool isInt = obj.canConvert(QMetaType::fromType<QVector<int>>());
|
||
|
|
int len;
|
||
|
|
if(isInt)
|
||
|
|
{
|
||
|
|
QVector<int> iarray = obj.value<QVector<int>>();
|
||
|
|
len = iarray.size();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
QVector<uint> iarray = obj.value<QVector<uint>>();
|
||
|
|
len = iarray.size();
|
||
|
|
}
|
||
|
|
QVector<int> Iarray(len);
|
||
|
|
for(int i = 0; i < len; i++)
|
||
|
|
{
|
||
|
|
if(isInt)
|
||
|
|
{
|
||
|
|
QVector<int> tiarray = obj.value<QVector<int>>();
|
||
|
|
Iarray[i] = tiarray[i];
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
QVector<uint> tiarray = obj.value<QVector<uint>>();
|
||
|
|
Iarray[i] = UIntToInt(tiarray[i]);
|
||
|
|
}
|
||
|
|
SendCMD += QString("%1\\%2\\").arg(JRPCpp::Int).arg(Iarray[i]);
|
||
|
|
NumOfArgs += 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
Done = true;
|
||
|
|
}
|
||
|
|
else if (obj.canConvert(QMetaType::fromType<QString>()))
|
||
|
|
{
|
||
|
|
QString str = obj.toString();
|
||
|
|
SendCMD += QString("%1/%2\\%3\\").arg(JRPCpp::ByteArray).arg(str.size()).arg(obj.toString().toUtf8().toHex());
|
||
|
|
NumOfArgs += 1;
|
||
|
|
Done = true;
|
||
|
|
}
|
||
|
|
else if (obj.canConvert(QMetaType::fromType<double>()))
|
||
|
|
{
|
||
|
|
double d = obj.toDouble();
|
||
|
|
SendCMD += QString("%1\\%2\\").arg(JRPCpp::Float).arg(d);
|
||
|
|
NumOfArgs += 1;
|
||
|
|
Done = true;
|
||
|
|
}
|
||
|
|
else if (obj.canConvert(QMetaType::fromType<float>()))
|
||
|
|
{
|
||
|
|
float fl = obj.toFloat();
|
||
|
|
SendCMD += QString("%1\\%2\\").arg(JRPCpp::Float).arg(fl);
|
||
|
|
NumOfArgs += 1;
|
||
|
|
Done = true;
|
||
|
|
}
|
||
|
|
else if (obj.canConvert(QMetaType::fromType<QVector<float>>()))
|
||
|
|
{
|
||
|
|
QVector<float> floatArray = obj.value<QVector<float>>();
|
||
|
|
if (!VM)
|
||
|
|
{
|
||
|
|
SendCMD += QString("%1/%2\\").arg(JRPCpp::ByteArray).arg(floatArray.size() * 4);
|
||
|
|
for (int i = 0; i < floatArray.size(); i++)
|
||
|
|
{
|
||
|
|
QByteArray bytes = QString::number(floatArray[i]).toUtf8();
|
||
|
|
Array.Reverse(bytes);
|
||
|
|
for (int q = 0; q < 4; q++)
|
||
|
|
SendCMD += QString::number(bytes[q]);
|
||
|
|
}
|
||
|
|
SendCMD += "\\";
|
||
|
|
NumOfArgs += 1;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
for (int i = 0; i < floatArray.size(); i++)
|
||
|
|
{
|
||
|
|
SendCMD += QString("%1\\%2\\").arg(JRPCpp::Float).arg(floatArray[i]);
|
||
|
|
NumOfArgs += 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
Done = true;
|
||
|
|
}
|
||
|
|
else if (obj is QByteArray)
|
||
|
|
{
|
||
|
|
QByteArray ByteArray = (QByteArray)obj;
|
||
|
|
SendCMD += JRPCpp::ByteArray.ToString() + "/" + ByteArray.Length + "\\";
|
||
|
|
for (int i = 0; i < ByteArray.Length; i++)
|
||
|
|
SendCMD += ByteArray[i].ToString("X2");
|
||
|
|
SendCMD += "\\";
|
||
|
|
NumOfArgs += 1;
|
||
|
|
Done = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!Done)
|
||
|
|
{
|
||
|
|
SendCMD += JRPCpp::Uint64.ToString() + "\\" + ConvertToUInt64(obj).ToString()+ "\\";
|
||
|
|
NumOfArgs += 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
SendCMD += "\"";
|
||
|
|
|
||
|
|
QString startSendCMD = "consolefeatures ver=" + JRPCVersion + " type=" + Type + (SystemThread ? " system" : "") +
|
||
|
|
(module != null ? " module=\"" + module + "\" ord=" + aOrdinal : "") +
|
||
|
|
(VM ? " VM" : "") +
|
||
|
|
" as=" + aArraySize + " params=\"A\\" + Address.ToString("X") + "\\A\\" + NumOfArgs + "\\" + SendCMD,
|
||
|
|
Responce;
|
||
|
|
if (NumOfArgs > 37)
|
||
|
|
throw new Exception("Can not use more than 37 paramaters in a call");
|
||
|
|
|
||
|
|
Responce = SendCommand(aConsole, startSendCMD);
|
||
|
|
QString Find = "buf_addr=";
|
||
|
|
while (Responce.Contains(Find))
|
||
|
|
{
|
||
|
|
System.Threading.Thread.Sleep(250);
|
||
|
|
uint aAddress = uint.Parse(Responce.SubQString(Responce.find(Find) + Find.Length), System.Globalization.NumberStyles.HexNumber);
|
||
|
|
Responce = SendCommand(aConsole, "consolefeatures " + Find + "0x" + address.ToString("X"));
|
||
|
|
}
|
||
|
|
console.ConversationTimeout = 2000;//reset the timeout
|
||
|
|
console.ConnectTimeout = 5000;
|
||
|
|
|
||
|
|
switch(Type)
|
||
|
|
{
|
||
|
|
case 1:/*Int*/
|
||
|
|
uint uVal = uint.Parse(Responce.SubQString(Responce.find(" ") + 1), System.Globalization.NumberStyles.HexNumber);
|
||
|
|
if(t == typeof(uint))
|
||
|
|
return uVal;
|
||
|
|
if (t == typeof(int))
|
||
|
|
return UIntToInt(uVal);
|
||
|
|
if (t == typeof(short))
|
||
|
|
return short.Parse(Responce.SubQString(Responce.find(" ") + 1), System.Globalization.NumberStyles.HexNumber);
|
||
|
|
if (t == typeof(ushort))
|
||
|
|
return ushort.Parse(Responce.SubQString(Responce.find(" ") + 1), System.Globalization.NumberStyles.HexNumber);
|
||
|
|
break;
|
||
|
|
case 2:/*String*/
|
||
|
|
QString sString = Responce.SubQString(Responce.find(" ") + 1);
|
||
|
|
if (t == QMetaType::fromType<QString>())
|
||
|
|
return sString;
|
||
|
|
if (t == typeof(char[]))
|
||
|
|
return sString.ToCharArray();
|
||
|
|
break;
|
||
|
|
case 3:/*Float*/
|
||
|
|
if (t == typeof(double))
|
||
|
|
return double.Parse(Responce.SubQString(Responce.find(" ") + 1));
|
||
|
|
if (t == typeof(float))
|
||
|
|
return float.Parse(Responce.SubQString(Responce.find(" ") + 1));;
|
||
|
|
break;
|
||
|
|
case 4:/*Byte*/
|
||
|
|
byte bByte = byte.Parse(Responce.SubQString(Responce.find(" ") + 1), System.Globalization.NumberStyles.HexNumber);
|
||
|
|
if (t == typeof(byte))
|
||
|
|
return bByte;
|
||
|
|
if (t == typeof(char))
|
||
|
|
return (char)bByte;
|
||
|
|
break;
|
||
|
|
case 8:/*UInt64*/
|
||
|
|
if (t == typeof(long))
|
||
|
|
return long.Parse(Responce.SubQString(Responce.find(" ") + 1), System.Globalization.NumberStyles.HexNumber);
|
||
|
|
if (t == typeof(unsigned long))
|
||
|
|
return unsigned long.Parse(Responce.SubQString(Responce.find(" ") + 1), System.Globalization.NumberStyles.HexNumber);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
if (Type == 5)//IntArray
|
||
|
|
{
|
||
|
|
QString String = Responce.SubQString(Responce.find(" ") + 1);
|
||
|
|
int Tmp = 0;
|
||
|
|
QString Temp = "";
|
||
|
|
QVector<uint> Uarray = new uint[8];
|
||
|
|
foreach (char Char1 in String)
|
||
|
|
{
|
||
|
|
if (Char1 != ',' && Char1 != ';')
|
||
|
|
Temp += Char1.ToString();
|
||
|
|
else
|
||
|
|
{
|
||
|
|
Uarray[Tmp] = uint.Parse(Temp, System.Globalization.NumberStyles.HexNumber);
|
||
|
|
Tmp += 1;
|
||
|
|
Temp = "";
|
||
|
|
}
|
||
|
|
if (Char1 == ';')
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
return Uarray;
|
||
|
|
}
|
||
|
|
if (Type == 6)//FloatArray
|
||
|
|
{
|
||
|
|
QString String = Responce.SubQString(Responce.find(" ") + 1);
|
||
|
|
int Tmp = 0;
|
||
|
|
QString Temp = "";
|
||
|
|
QVector<float> Farray = new float[ArraySize];
|
||
|
|
foreach (char Char1 in String)
|
||
|
|
{
|
||
|
|
if (Char1 != ',' && Char1 != ';')
|
||
|
|
Temp += Char1.ToString();
|
||
|
|
else
|
||
|
|
{
|
||
|
|
Farray[Tmp] = float.Parse(Temp);
|
||
|
|
Tmp += 1;
|
||
|
|
Temp = "";
|
||
|
|
}
|
||
|
|
if (Char1 == ';')
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
return Farray;
|
||
|
|
}
|
||
|
|
if (Type == 7)//ByteArray
|
||
|
|
{
|
||
|
|
QString String = Responce.SubQString(Responce.find(" ") + 1);
|
||
|
|
int Tmp = 0;
|
||
|
|
QString Temp = "";
|
||
|
|
QByteArray Barray = new byte[ArraySize];
|
||
|
|
foreach (char Char1 in String)
|
||
|
|
{
|
||
|
|
if (Char1 != ',' && Char1 != ';')
|
||
|
|
Temp += Char1.ToString();
|
||
|
|
else
|
||
|
|
{
|
||
|
|
Barray[Tmp] = byte.Parse(Temp);
|
||
|
|
Tmp += 1;
|
||
|
|
Temp = "";
|
||
|
|
}
|
||
|
|
if (Char1 == ';')
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
return Barray;
|
||
|
|
}
|
||
|
|
if (Type == JRPCpp::Uint64Array)
|
||
|
|
{
|
||
|
|
QString String = Responce.SubQString(Responce.find(" ") + 1);
|
||
|
|
int Tmp = 0;
|
||
|
|
QString Temp = "";
|
||
|
|
QVector<unsigned long> unsigned longArray = new unsigned long[ArraySize];
|
||
|
|
foreach (char Char1 in String)
|
||
|
|
{
|
||
|
|
if (Char1 != ',' && Char1 != ';')
|
||
|
|
Temp += Char1.ToString();
|
||
|
|
else
|
||
|
|
{
|
||
|
|
unsigned longArray[Tmp] =unsigned long.Parse(Temp);
|
||
|
|
Tmp += 1;
|
||
|
|
Temp = "";
|
||
|
|
}
|
||
|
|
if (Char1 == ';')
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
if(t == typeof(unsigned long))
|
||
|
|
return unsigned longArray;
|
||
|
|
else if (t == typeof(long))
|
||
|
|
{
|
||
|
|
QVector<long> longArray = new long[ArraySize];
|
||
|
|
for (int i = 0; i < aArraySize; i++)
|
||
|
|
longArray[i] = BitConverter.ToInt64(BitConverter.GetBytes(unsigned longArray[i]), 0);
|
||
|
|
return longArray;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (Type == Void)
|
||
|
|
return 0;
|
||
|
|
return unsigned long.Parse(Responce.SubQString(Responce.find(" ") + 1), System.Globalization.NumberStyles.HexNumber);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void JRPCpp::ReverseBytes(QByteArray buffer, int groupSize)
|
||
|
|
{
|
||
|
|
if (buffer.Length % groupSize != 0)
|
||
|
|
throw new ArgumentException("Group size must be a multiple of the buffer length", "groupSize");
|
||
|
|
int num1 = 0;
|
||
|
|
while (num1 < buffer.Length)
|
||
|
|
{
|
||
|
|
int index1 = num1;
|
||
|
|
for (int index2 = num1 + groupSize - 1; index1 < index2; --index2)
|
||
|
|
{
|
||
|
|
byte num2 = buffer[index1];
|
||
|
|
buffer[index1] = buffer[index2];
|
||
|
|
buffer[index2] = num2;
|
||
|
|
++index1;
|
||
|
|
}
|
||
|
|
num1 += groupSize;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
float JRPCpp::ReadFloat(const IXboxConsole &aConsole, uint aAddress)
|
||
|
|
{
|
||
|
|
QByteArray buff = GetMemory(aConsole, aAddress, 4);
|
||
|
|
ReverseBytes(buff, 4);
|
||
|
|
return buff.toFloat();
|
||
|
|
}
|
||
|
|
|
||
|
|
QVector<float> JRPCpp::ReadFloat(const IXboxConsole &aConsole, uint aAddress, uint aArraySize)
|
||
|
|
{
|
||
|
|
QVector<float> result(aArraySize);
|
||
|
|
QByteArray buff = GetMemory(aConsole, aAddress, aArraySize * 4);
|
||
|
|
ReverseBytes(buff, 4);
|
||
|
|
for (int i = 0; i < aArraySize; i++)
|
||
|
|
result[i] = buff.mid(i * 4, 4).toFloat();
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
qint16 JRPCpp::ReadInt16(const IXboxConsole &aConsole, uint aAddress)
|
||
|
|
{
|
||
|
|
QByteArray buff = GetMemory(aConsole, aAddress, 2);
|
||
|
|
ReverseBytes(buff, 2);
|
||
|
|
return buff.toInt();
|
||
|
|
}
|
||
|
|
|
||
|
|
QVector<qint16> JRPCpp::ReadInt16(const IXboxConsole &aConsole, uint aAddress, uint aArraySize)
|
||
|
|
{
|
||
|
|
QVector<qint16> result(aArraySize);
|
||
|
|
QByteArray buff = GetMemory(aConsole, aAddress, aArraySize * 2);
|
||
|
|
ReverseBytes(buff, 2);
|
||
|
|
for (int i = 0; i < aArraySize; i++)
|
||
|
|
result[i] = buff.mid(i * 2, 2).toInt();
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
ushort JRPCpp::ReadUInt16(const IXboxConsole &aConsole, uint aAddress)
|
||
|
|
{
|
||
|
|
QByteArray buff = GetMemory(aConsole, aAddress, 2);
|
||
|
|
ReverseBytes(buff, 2);
|
||
|
|
return buff.toUInt();
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteByte(const IXboxConsole &aConsole, uint aAddress, byte aValue)
|
||
|
|
{
|
||
|
|
SetMemory(aConsole, aAddress, new byte[1] { aValue });
|
||
|
|
}
|
||
|
|
|
||
|
|
QVector<quint16> JRPCpp::ReadUInt16(const IXboxConsole &aConsole, uint aAddress, uint aArraySize)
|
||
|
|
{
|
||
|
|
ushort[] Return = new ushort[ArraySize];
|
||
|
|
QByteArray Buff = GetMemory(aConsole, aAddress, aArraySize * 2);
|
||
|
|
ReverseBytes(Buff, 2);
|
||
|
|
for (int i = 0; i < aArraySize; i++)
|
||
|
|
Return[i] = BitConverter.ToUInt16(Buff, i * 2);
|
||
|
|
return Return;
|
||
|
|
}
|
||
|
|
|
||
|
|
int JRPCpp::ReadInt32(const IXboxConsole &aConsole, uint aAddress)
|
||
|
|
{
|
||
|
|
QByteArray Buff = GetMemory(aConsole, aAddress, 4);
|
||
|
|
ReverseBytes(Buff, 4);
|
||
|
|
return BitConverter.ToInt32(Buff, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
QVector<qint32> JRPCpp::ReadInt32(const IXboxConsole &aConsole, uint aAddress, uint aArraySize)
|
||
|
|
{
|
||
|
|
int[] Return = new int[ArraySize];
|
||
|
|
QByteArray Buff = GetMemory(aConsole, aAddress, aArraySize * 4);
|
||
|
|
ReverseBytes(Buff, 4);
|
||
|
|
for (int i = 0; i < aArraySize; i++)
|
||
|
|
Return[i] = BitConverter.ToInt32(Buff, i * 4);
|
||
|
|
return Return;
|
||
|
|
}
|
||
|
|
|
||
|
|
uint JRPCpp::ReadUInt32(const IXboxConsole &aConsole, uint aAddress)
|
||
|
|
{
|
||
|
|
QByteArray Buff = GetMemory(aConsole, aAddress, 4);
|
||
|
|
ReverseBytes(Buff, 4);
|
||
|
|
return BitConverter.ToUInt32(Buff, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
QVector<quint32> JRPCpp::ReadUInt32(const IXboxConsole &aConsole, uint aAddress, uint aArraySize)
|
||
|
|
{
|
||
|
|
uint[] Return = new uint[ArraySize];
|
||
|
|
QByteArray Buff = GetMemory(aConsole, aAddress, aArraySize * 4);
|
||
|
|
ReverseBytes(Buff, 4);
|
||
|
|
for (int i = 0; i < aArraySize; i++)
|
||
|
|
Return[i] = BitConverter.ToUInt32(Buff, i * 4);
|
||
|
|
return Return;
|
||
|
|
}
|
||
|
|
|
||
|
|
qint64 JRPCpp::ReadInt64(const IXboxConsole &aConsole, uint aAddress)
|
||
|
|
{
|
||
|
|
QByteArray buff = GetMemory(aConsole, aAddress, 8);
|
||
|
|
ReverseBytes(buff, 8);
|
||
|
|
return buff.toInt();
|
||
|
|
}
|
||
|
|
|
||
|
|
quint64 JRPCpp::ReadUInt64(const IXboxConsole &aConsole, uint aAddress)
|
||
|
|
{
|
||
|
|
QByteArray buff = GetMemory(aConsole, aAddress, 8);
|
||
|
|
ReverseBytes(buff, 8);
|
||
|
|
return buff.toUInt();
|
||
|
|
}
|
||
|
|
|
||
|
|
QVector<quint64> JRPCpp::ReadUInt64(const IXboxConsole &aConsole, uint aAddress, uint aArraySize)
|
||
|
|
{
|
||
|
|
QVector<quint64>result(aArraySize);
|
||
|
|
QByteArray buff = GetMemory(aConsole, aAddress, aArraySize * 8);
|
||
|
|
ReverseBytes(buff, 8);
|
||
|
|
for (int i = 0; i < aArraySize; i++)
|
||
|
|
result[i] = buff.mid(i * 8, 8).toUInt();
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
QString JRPCpp::ReadString(const IXboxConsole &aConsole, uint aAddress, uint size)
|
||
|
|
{
|
||
|
|
QByteArray buff = GetMemory(aConsole, aAddress, size);
|
||
|
|
return QString::fromUtf8(buff);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::SetMemory(const IXboxConsole &aConsole, uint aAddress, QByteArray aData)
|
||
|
|
{
|
||
|
|
uint out;
|
||
|
|
aConsole.DebugTarget.SetMemory(aAddress, (uint)aData.size(), aData, &out);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteSByte(const IXboxConsole &aConsole, uint aAddress, byte aValue)
|
||
|
|
{
|
||
|
|
SetMemory(aConsole, aAddress, QString::number(aValue).toUtf8());
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteSByte(const IXboxConsole &aConsole, uint aAddress, QByteArray aValue)
|
||
|
|
{
|
||
|
|
QByteArray bytes;
|
||
|
|
foreach (byte b, aValue)
|
||
|
|
bytes.push_back(b);
|
||
|
|
SetMemory(aConsole, aAddress, bytes);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteByte(const IXboxConsole &aConsole, uint aAddress, byte aValue)
|
||
|
|
{
|
||
|
|
SetMemory(aConsole, aAddress, QString::number(aValue).toUtf8());
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteByte(const IXboxConsole &aConsole, uint aAddress, QByteArray aValue)
|
||
|
|
{
|
||
|
|
SetMemory(aConsole, aAddress, aValue);
|
||
|
|
}
|
||
|
|
|
||
|
|
void JRPCpp::WriteBool(const IXboxConsole &aConsole, uint aAddress, bool aValue)
|
||
|
|
{
|
||
|
|
SetMemory(aConsole, aAddress, QString::number((aValue ? 1 : 0)).toUtf8());
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
T JRPCpp::Call(const IXboxConsole &aConsole, uint aAddress, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return (T)CallArgs(aConsole, true, TypeToType(false), QMetaType::fromType<T>(), nullptr, 0, aAddress, 0, false, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
T JRPCpp::Call(const IXboxConsole &aConsole, QString aModule, int aOrdinal, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return (T)CallArgs(aConsole, true, TypeToType(false), QMetaType::fromType<T>(), aModule, aOrdinal, 0, 0, false, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
T JRPCpp::Call(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return (T)CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(false), QMetaType::fromType<T>(), nullptr, 0, aAddress, 0, false, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
T JRPCpp::Call(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return (T)CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(false), QMetaType::fromType<T>(), aModule, aOrdinal, 0, 0, false, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
QVector<T> JRPCpp::CallArray(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, uint aArraySize, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
if (aArraySize == 0)
|
||
|
|
return new T[1];
|
||
|
|
return (T[])CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(true), QMetaType::fromType<T>(), aModule, aOrdinal, 0, aArraySize, false, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
QVector<T> JRPCpp::CallArray(const IXboxConsole &aConsole, uint aAddress, uint aArraySize, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
if (aArraySize == 0)
|
||
|
|
return new T[1];
|
||
|
|
return (T[])CallArgs(aConsole, true, TypeToType(true), QMetaType::fromType<T>(), nullptr, 0, aAddress, aArraySize, false, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
QVector<T> JRPCpp::CallArray(const IXboxConsole &aConsole, QString aModule, int aOrdinal, uint aArraySize, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
if (aArraySize == 0)
|
||
|
|
return new T[1];
|
||
|
|
return (T[])CallArgs(aConsole, true, TypeToType(true), QMetaType::fromType<T>(), aModule, aOrdinal, 0, aArraySize, false, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
QVector<T> JRPCpp::CallArray(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, uint aArraySize, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
if (aArraySize == 0)
|
||
|
|
return new T[1];
|
||
|
|
return (T[])CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(true), QMetaType::fromType<T>(), nullptr, 0, aAddress, aArraySize, false, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
T JRPCpp::CallVM(const IXboxConsole &aConsole, uint aAddress, QVector<QVariant> aArguments)
|
||
|
|
{
|
||
|
|
return (T)CallArgs(aConsole, true, TypeToType(false), QMetaType::fromType<T>(), nullptr, 0, aAddress, 0, true, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
T JRPCpp::CallVM(const IXboxConsole &aConsole, QString aModule, int aOrdinal, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return (T)CallArgs(aConsole, true, TypeToType(false), QMetaType::fromType<T>(), aModule, aOrdinal, 0, 0, true, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
T JRPCpp::CallVM(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return (T)CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(false), QMetaType::fromType<T>(), nullptr, 0, aAddress, 0, true, aArguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
T JRPCpp::CallVM(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, const QVector<QVariant> &aArguments)
|
||
|
|
{
|
||
|
|
return (T)CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(false), QMetaType::fromType<T>(), aModule, aOrdinal, 0, 0, true, aArguments);
|
||
|
|
}
|