#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())) return (ulong)aVariant.value(); else if (aVariant.canConvert(QMetaType::fromType())) return (ulong)aVariant.value(); else if (aVariant.canConvert(QMetaType::fromType())) return (ulong)aVariant.value(); else if (aVariant.canConvert(QMetaType::fromType())) return (ulong)aVariant.value(); else if (aVariant.canConvert(QMetaType::fromType())) return (ulong)aVariant.value(); else if (aVariant.canConvert(QMetaType::fromType())) return (ulong)aVariant.value(); else if (aVariant.canConvert(QMetaType::fromType())) return (ulong)aVariant.value(); else if (aVariant.canConvert(QMetaType::fromType())) return (ulong)aVariant.value(); else if (aVariant.canConvert(QMetaType::fromType())) return (ulong)aVariant.value(); else if (aVariant.canConvert(QMetaType::fromType())) return (ulong)aVariant.value(); 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 JRPCpp::ReadInt64(const IXboxConsole &aConsole, uint aAddress, uint aArraySize) { QVector 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 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 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 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 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 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 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 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 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 &aArguments) { CallArgs(aConsole, true, JRPCpp::Void, QMetaType::fromType(), nullptr, 0, aAddress, 0, false, aArguments); } void JRPCpp::CallVoid(const IXboxConsole &aConsole, QString aModule, int aOrdinal, const QVector &aArguments) { CallArgs(aConsole, true, JRPCpp::Void, QMetaType::fromType(), aModule, aOrdinal, 0, 0, false, aArguments); } void JRPCpp::CallVoid(const IXboxConsole &aConsole, ThreadType aType, uint aAddress, const QVector &aArguments) { CallArgs(aConsole, aType == ThreadType::SystemType, JRPCpp::Void, QMetaType::fromType(), nullptr, 0, aAddress, 0, false, aArguments); } void JRPCpp::CallVoid(const IXboxConsole &aConsole, ThreadType aType, QString aModule, int aOrdinal, const QVector &aArguments) { CallArgs(aConsole, aType == ThreadType::SystemType, JRPCpp::Void, QMetaType::fromType(), aModule, aOrdinal, 0, 0, false, aArguments); } template QVector JRPCpp::ArrayReturn(const IXboxConsole &aConsole, uint aAddress, uint Size) { if(Size == 0) return new T[1]; QMetaType type = QMetaType::fromType(); QVariant result; if (type == QMetaType::fromType()) result.fromValue(ReadInt16(aConsole, aAddress, Size)); if (type == QMetaType::fromType()) result.fromValue(ReadUInt16(aConsole, aAddress, Size)); if (type == QMetaType::fromType()) result.fromValue(ReadInt32(aConsole, aAddress, Size)); if (type == QMetaType::fromType()) result.fromValue(ReadUInt32(aConsole, aAddress, Size)); if (type == QMetaType::fromType()) result.fromValue(ReadInt64(aConsole, aAddress, Size)); if (type == QMetaType::fromType()) result.fromValue(ReadUInt64(aConsole, aAddress, Size)); if (type == QMetaType::fromType()) result.fromValue(ReadFloat(aConsole, aAddress, Size)); if (type == QMetaType::fromType()) result.fromValue(GetMemory(aConsole, aAddress, Size)); return (T[])result; } QString JRPCpp::CallString(const IXboxConsole &aConsole, uint aAddress, const QVector &aArguments) { return CallArgs(aConsole, true, JRPCpp::String, QMetaType::fromType(), nullptr, 0, aAddress, 0, false, aArguments) .toString(); } QString JRPCpp::CallString(const IXboxConsole &aConsole, QString aModule, int aOrdinal, const QVector &aArguments) { return CallArgs(aConsole, true, JRPCpp::String, QMetaType::fromType(), aModule, aOrdinal, 0, 0, false, aArguments) .toString(); } QString JRPCpp::CallString(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, const QVector &aArguments) { return CallArgs(aConsole, Type == ThreadType::SystemType, JRPCpp::String, QMetaType::fromType(), nullptr, 0, aAddress, 0, false, aArguments) .toString(); } QString JRPCpp::CallString(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, const QVector &aArguments) { return CallArgs(aConsole, Type == ThreadType::SystemType, JRPCpp::String, QMetaType::fromType(), 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 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 &aArguments) { CallArgs(aConsole, true, JRPCpp::Void, QMetaType::fromType(), nullptr, 0, aAddress, 0, true, aArguments); } void JRPCpp::CallVMVoid(const IXboxConsole &aConsole, QString aModule, int aOrdinal, const QVector &aArguments) { CallArgs(aConsole, true, JRPCpp::Void, QMetaType::fromType(), aModule, aOrdinal, 0, 0, true, aArguments); } void JRPCpp::CallVMVoid(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, const QVector &aArguments) { CallArgs(aConsole, Type == ThreadType::SystemType, JRPCpp::Void, QMetaType::fromType(), nullptr, 0, aAddress, 0, true, aArguments); } void JRPCpp::CallVMVoid(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, const QVector &aArguments) { CallArgs(aConsole, Type == ThreadType::SystemType, JRPCpp::Void, QMetaType::fromType(), aModule, aOrdinal, 0, 0, true, aArguments); } template QVector CallVMArray(const IXboxConsole &aConsole, uint aAddress, uint aArraySize, const QVector &aArguments) { if (aArraySize == 0) return new T[1]; return (T[])CallArgs(aConsole, true, TypeToType(true), QMetaType::fromType(), nullptr, 0, aAddress, aArraySize, true, aArguments); } template QVector CallVMArray(const IXboxConsole &aConsole, QString aModule, int aOrdinal, uint aArraySize, const QVector &aArguments) { if (aArraySize == 0) return new T[1]; return (T[])CallArgs(aConsole, true, TypeToType(true), QMetaType::fromType(), aModule, aOrdinal, 0, aArraySize, true, aArguments); } template QVector CallVMArray(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, uint aArraySize, const QVector &aArguments) { if (aArraySize == 0) return new T[1]; return (T[])CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(true), QMetaType::fromType(), nullptr, 0, aAddress, aArraySize, true, aArguments); } template QVector CallVMArray(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, uint aArraySize, const QVector &aArguments) { if (aArraySize == 0) return new T[1]; return (T[])CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(true), QMetaType::fromType(), aModule, aOrdinal, 0, aArraySize, true, aArguments); } QString JRPCpp::CallVMString(const IXboxConsole &aConsole, uint aAddress, const QVector &aArguments) { return CallArgs(aConsole, true, JRPCpp::String, QMetaType::fromType(), nullptr, 0, aAddress, 0, true, aArguments).toString(); } QString JRPCpp::CallVMString(const IXboxConsole &aConsole, QString aModule, int aOrdinal, const QVector &aArguments) { return CallArgs(aConsole, true, JRPCpp::String, QMetaType::fromType(), aModule, aOrdinal, 0, 0, true, aArguments).toString(); } QString JRPCpp::CallVMString(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, const QVector &aArguments) { return CallArgs(aConsole, Type == ThreadType::SystemType, JRPCpp::String, QMetaType::fromType(), nullptr, 0, aAddress, 0, true, aArguments) .toString(); } QString JRPCpp::CallVMString(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, const QVector &aArguments) { return CallArgs(aConsole, Type == ThreadType::SystemType, JRPCpp::String, QMetaType::fromType(), 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 &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())) { SendCMD += QString("%1\\%2\\") .arg(JRPCpp::Int) .arg(obj.value()); NumOfArgs += 1; Done = true; } if (obj.canConvert(QMetaType::fromType()) || obj.canConvert(QMetaType::fromType()) || obj.canConvert(QMetaType::fromType())) { if (obj.canConvert(QMetaType::fromType())) { SendCMD += QString("%1\\%2\\") .arg(JRPCpp::Int) .arg(obj.value()); } else { SendCMD += QString("%1\\%2\\") .arg(JRPCpp::Int) .arg(obj.value()); } NumOfArgs += 1; Done = true; } else if (obj.canConvert(QMetaType::fromType>()) || obj.canConvert(QMetaType::fromType>())) { if (!VM) { QByteArray array = IntArrayToByte(obj.value>()); 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>()); int len; if(isInt) { QVector iarray = obj.value>(); len = iarray.size(); } else { QVector iarray = obj.value>(); len = iarray.size(); } QVector Iarray(len); for(int i = 0; i < len; i++) { if(isInt) { QVector tiarray = obj.value>(); Iarray[i] = tiarray[i]; } else { QVector tiarray = obj.value>(); 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 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 d = obj.toDouble(); SendCMD += QString("%1\\%2\\").arg(JRPCpp::Float).arg(d); NumOfArgs += 1; Done = true; } else if (obj.canConvert(QMetaType::fromType())) { float fl = obj.toFloat(); SendCMD += QString("%1\\%2\\").arg(JRPCpp::Float).arg(fl); NumOfArgs += 1; Done = true; } else if (obj.canConvert(QMetaType::fromType>())) { QVector floatArray = obj.value>(); 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()) 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 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 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 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 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 JRPCpp::ReadFloat(const IXboxConsole &aConsole, uint aAddress, uint aArraySize) { QVector 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 JRPCpp::ReadInt16(const IXboxConsole &aConsole, uint aAddress, uint aArraySize) { QVector 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 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 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 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 JRPCpp::ReadUInt64(const IXboxConsole &aConsole, uint aAddress, uint aArraySize) { QVectorresult(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 T JRPCpp::Call(const IXboxConsole &aConsole, uint aAddress, const QVector &aArguments) { return (T)CallArgs(aConsole, true, TypeToType(false), QMetaType::fromType(), nullptr, 0, aAddress, 0, false, aArguments); } template T JRPCpp::Call(const IXboxConsole &aConsole, QString aModule, int aOrdinal, const QVector &aArguments) { return (T)CallArgs(aConsole, true, TypeToType(false), QMetaType::fromType(), aModule, aOrdinal, 0, 0, false, aArguments); } template T JRPCpp::Call(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, const QVector &aArguments) { return (T)CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(false), QMetaType::fromType(), nullptr, 0, aAddress, 0, false, aArguments); } template T JRPCpp::Call(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, const QVector &aArguments) { return (T)CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(false), QMetaType::fromType(), aModule, aOrdinal, 0, 0, false, aArguments); } template QVector JRPCpp::CallArray(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, uint aArraySize, const QVector &aArguments) { if (aArraySize == 0) return new T[1]; return (T[])CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(true), QMetaType::fromType(), aModule, aOrdinal, 0, aArraySize, false, aArguments); } template QVector JRPCpp::CallArray(const IXboxConsole &aConsole, uint aAddress, uint aArraySize, const QVector &aArguments) { if (aArraySize == 0) return new T[1]; return (T[])CallArgs(aConsole, true, TypeToType(true), QMetaType::fromType(), nullptr, 0, aAddress, aArraySize, false, aArguments); } template QVector JRPCpp::CallArray(const IXboxConsole &aConsole, QString aModule, int aOrdinal, uint aArraySize, const QVector &aArguments) { if (aArraySize == 0) return new T[1]; return (T[])CallArgs(aConsole, true, TypeToType(true), QMetaType::fromType(), aModule, aOrdinal, 0, aArraySize, false, aArguments); } template QVector JRPCpp::CallArray(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, uint aArraySize, const QVector &aArguments) { if (aArraySize == 0) return new T[1]; return (T[])CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(true), QMetaType::fromType(), nullptr, 0, aAddress, aArraySize, false, aArguments); } template T JRPCpp::CallVM(const IXboxConsole &aConsole, uint aAddress, QVector aArguments) { return (T)CallArgs(aConsole, true, TypeToType(false), QMetaType::fromType(), nullptr, 0, aAddress, 0, true, aArguments); } template T JRPCpp::CallVM(const IXboxConsole &aConsole, QString aModule, int aOrdinal, const QVector &aArguments) { return (T)CallArgs(aConsole, true, TypeToType(false), QMetaType::fromType(), aModule, aOrdinal, 0, 0, true, aArguments); } template T JRPCpp::CallVM(const IXboxConsole &aConsole, ThreadType Type, uint aAddress, const QVector &aArguments) { return (T)CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(false), QMetaType::fromType(), nullptr, 0, aAddress, 0, true, aArguments); } template T JRPCpp::CallVM(const IXboxConsole &aConsole, ThreadType Type, QString aModule, int aOrdinal, const QVector &aArguments) { return (T)CallArgs(aConsole, Type == ThreadType::SystemType, TypeToType(false), QMetaType::fromType(), aModule, aOrdinal, 0, 0, true, aArguments); }