Register for your free account! | Forgot your password?

Go Back   elitepvpers > Popular Games > Silkroad Online > SRO Private Server > SRO PServer Questions & Answers
You last visited: Today at 17:30

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



vSRO patch client module version without SMC

Discussion on vSRO patch client module version without SMC within the SRO PServer Questions & Answers forum part of the SRO Private Server category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Sep 2011
Posts: 121
Received Thanks: 32
Question vSRO patch client module version without SMC

Hello,

I would like to know if its possible to add an update patch without using SMC. The reason I need this because I want to automate it.

I see when a patch is added a new record is inserted into _ModuleVersion and also each file included in the patch is represented in _ModuleVersionFile. I have a problem where nToBePacked = 1. I have no idea how to "pack" the file.

Thanks in advance
thehaifisch is offline  
Old 10/26/2023, 12:39   #2
Trade Restricted


 
elite*gold: LOCKED
The Black Market: 115/0/0
Join Date: Apr 2022
Posts: 1,334
Received Thanks: 490
If you're willing to upload a new client with every update it is surely do able otherwise no as the client from players are not going to update.
Athena' is offline  
Old 10/26/2023, 12:48   #3
 
elite*gold: 0
Join Date: Sep 2011
Posts: 121
Received Thanks: 32
Quote:
Originally Posted by Athena' View Post
If you're willing to upload a new client with every update it is surely do able otherwise no as the client from players are not going to update.
I would like to replace the client patch functionality of SMC with something else that can be automated. But of course I want clients to update automatically.
thehaifisch is offline  
Old 10/26/2023, 15:29   #4
 
elite*gold: 0
Join Date: Jan 2009
Posts: 314
Received Thanks: 686
It's definitely possible but not in the way you think, at least from what I understood from your post.

Just adding rows to _ModuleVersion and _ModuleVersionFile is also not enough as neither DownloadServer nor GatewayServer have received information about this.

nToBePacked just means the files are supposed to go into a PackFile (.pk2)
You might be confusing this with the required compression used by SMC which is zLib in vSRO and lzma in some other clients.

You can either write your own launcher that downloads from a cdn based on a "version.txt" file, thus never modifying the actual silkroad version but importing the files into pk2.

Or you can write a clientless tool that acts like SMC. Meaning its communicating via GlobalManager to automate the patching.

Step 0. Fix your SecurityApi

There are some oversights in @ 's . They only happen in backend communication, that's why they went unnoticed.

0x1001 is supposed to be ignored from CRC and Sequence.
Code:
// Original
byte sb1 = GenerateCountByte(true);

// Fixed
byte sb1 = opcode == 0x1001 ? (byte)0 : GenerateCountByte(true);

// Original
byte sb2 = GenerateCheckByte(writer.GetBytes()); 

// Fixed
byte sb2 = opcode == 0x1001 ? (byte)0 : GenerateCheckByte(writer.GetBytes());

// Original
byte expected_count = GenerateCountByte(true); 
 
// Fixed
byte expected_count = packet_opcode == 0x1001 ? (byte)0 : GenerateCountByte(true);

// Original
byte expected_crc = GenerateCheckByte(buffer.Buffer); 

// Fixed
byte expected_crc = packet_opcode == 0x1001 ? (byte)0 : GenerateCheckByte(buffer.Data);
The FormatPacket is out of order thus messing with CRC and Sequence. I'm not sure if this one is 100% needed, but just in case.

Code:
// Original
ushort parts = 0;

PacketWriter final = new PacketWriter();
PacketWriter final_data = new PacketWriter();

byte[] input_data = packet.GetBytes();
PacketReader input_reader = new PacketReader(input_data);

TransferBuffer workspace = new TransferBuffer(4089, 0, input_data.Length);

while (workspace.Size > 0)
{
    PacketWriter part_data = new PacketWriter();

    int cur_size = workspace.Size > 4089 ? 4089 : workspace.Size; // Max buffer size is 4kb for the client

    part_data.Write((byte)0); // Data flag

    part_data.Write(input_data, workspace.Offset, cur_size);

    workspace.Offset += cur_size;
    workspace.Size -= cur_size; // Update the size

    final_data.Write(FormatPacket(0x600D, part_data.GetBytes(), false));

    ++parts; // Track how many parts there are
}

// Write the final header packet to the front of the packet
PacketWriter final_header = new PacketWriter();
final_header.Write((byte)1); // Header flag
final_header.Write((short)parts);
final_header.Write(packet.Opcode);
final.Write(FormatPacket(0x600D, final_header.GetBytes(), false));
Code:
// Fixed
ushort parts = 0;

PacketWriter final = new PacketWriter();
PacketWriter final_data = new PacketWriter();

byte[] input_data = packet.GetBytes();

PacketWriter header = new PacketWriter();
header.Write((byte)1); //Header flag
header.Write((ushort)((input_data.Length / 4089) + (input_data.Length % 4089 != 0 ? 1 : 0)));
header.Write(packet.Opcode);
final.Write(this.FormatPacket(0x600D, header.GetBytes(), false));

TransferBuffer workspace = new TransferBuffer(4089, 0, input_data.Length);

while (workspace.Length > 0)
{
    PacketWriter part_data = new PacketWriter();

    int cur_size = workspace.Length > 4089 ? 4089 : workspace.Length; // Max buffer size is 4kb for the client

    part_data.Write((byte)0); // Data flag

    part_data.Write(input_data, workspace.Offset, cur_size);

    workspace.Offset += cur_size;
    workspace.Length -= cur_size; // Update the size

    final_data.Write(this.FormatPacket(0x600D, part_data.GetBytes(), false));

    ++parts; // Track how many parts there are
}
Step 1.
Login as an SMC that has the required SecurityDescriptions

0x7001 - SM_LOGIN_REQ
Code:
2	ushort	Username.Length
*	string	Username
2	ushort	PasswordHash.Length
*	string	PasswordHash //MD5
2	ushort	SSNumber2Hash.Length
*	string	SSNumber2Hash //MD5, can be empty
4	uint	ProtocolVersion //24
0xB001 - SM_LOGIN_ACK
Code:
1	byte	result
if(result == 1)
{
	1	byte	curentSecurityGroup
	1	byte	currentDivision
    
    // SecurityDescriptionData (optional)
    // See https://github.com/DummkopfOfHachtenduden/SilkroadDoc/wiki/0xA003-FRAMEWORK_MSG_CERTIFICATION_ACK.md

}
else if(result == 0x02)
{
	1	byte	errorCode
	//01 = cannot connect to division manager (wrong version)
	//02 = cannot connect to division manager (invalid user info)
	//03 = cannot connect to division manager (server internal error)
	//04 = cannot connect to division manager (access denied)
}
Step 2.
Request the architecture info (optional)

0x7002 - SM_ARCHITECTURE_REQ
Code:
// Empty
0xB002 - SM_ARCHITECTURE_ACK
Code:
See https://github.com/DummkopfOfHachtenduden/SilkroadDoc/wiki/0xA003-FRAMEWORK_MSG_CERTIFICATION_ACK.md
Step 3.
Request module version info

0x7003 - SM_MODULE_VERSION_REQ
Code:
// Empty
0xB003 - SM_MODULE_VERSION_ACK
Code:
1	byte	result

while(true)
{
	1	byte	entryFlag
	if(entryFlag == 0)
		break;

	4	uint	nID
	1	byte	nDivisionID
	1	byte	nContentID
	1	byte	nModuleID
	4	uint	nVersion
	64	string	szVersion
	256	string	szDesc
	1	byte	nValid //Always 1 as GlobalManager culls all obsolete versions
}
Step 4.
Prepare patch on the front servers [GatewayServer(s) and DownloadServer(s)]
GlobalManager will give you the latest version info so you can compare your local files against it.

0x7104 - SM_MODULE_PATCH_PREPARE_REQ
Code:
1   byte    ModuleID        // SR_Client or ServiceManager
1   byte    ContentID
0xB104 - SM_MODULE_PATCH_PREPARE_ACK
Code:
1   byte    result
if(result == 0x01)
{
    //ModuleVersion@HEAD
    while(true)
    {
        1   byte    entryFlag
        if(entryFlag == 0)
            break;    
        
        4   uint    nID
        1   byte    nDivisionID
        1   byte    nContentID
        1   byte    nModuleID
        4   uint    nVersion
        64	string	szVersion
        256	string	szDesc
        1	byte	nValid // always 1 as GlobalManager culls all obsolete versions
    }

    while(true)
    {
        1   byte    entryFlag
        if(entryFlag == 0)
            break;    
        
        4   uint    nID
        4   uint    nVersion
        1   byte    nDivisionID
        1   byte    nContentID
        1   byte    nModuleID
        256 string  szFilename
        256 string  szPath
        4   uint    nFileSize
        1   byte    nFileType
        4   uint    nFileTypeVersion //1001 part of JMXV*****
        1   byte    nToBePacked
        2   ushort  timeModified.Year
        2   ushort  timeModified.Month
        2   ushort  timeModified.Day
        2   ushort  timeModified.Hour
        2   ushort  timeModified.Minute
        2   ushort  timeModified.Second
        4   uint    timeModified.Microsecond
        1   byte    nValid
    }
}
else if(result == 0x02)
{
    1   byte    errorCode
    //01 = "cannot prepare patch : another user patch in progress"
    //02 = "cannot prepare patch : 5:DownloadServer is offline"
    //03 = "cannot prepare patch : DB error"
    //?? = "cannot prepare patch : front server prepare patch fail"    
}
Step 5.
Compress your workspace with zLib. C#s DeflateStream only works for decompression.
The zLib from the works fine

Step 6.
Make an upload request to GlobalManager.

0x7100 - SM_MODULE_PATCH_UPLOAD_REQ (Massive)
Code:
4	uint	nID
1	byte	nDivisionID
1	byte	nContentID
1	byte	nModuleID
1	uint	nVersion
64	string	szVersion
256	string	szDesc
1	byte	nValid // always 1 as GlobalManager culls all obsolete versions

2   ushort  fileCount
foreach(file)
{
    4   uint    nID
    4   uint    nVersion
    1   byte    nDivisionID
    1   byte    nContentID
    1   byte    nModuleID
    256 string  szFilename
    256 string  szPath
    4   uint    nFileSize
    1   byte    nFileType
    4   uint    nFileTypeVersion //1001 part of JMXV*****
    1   byte    nToBePacked
    2   ushort  timeModified.Year
    2   ushort  timeModified.Month
    2   ushort  timeModified.Day
    2   ushort  timeModified.Hour
    2   ushort  timeModified.Minute
    2   ushort  timeModified.Second
    4   uint    timeModified.Microsecond
    1   byte    nValid
}
0xB100 - SM_MODULE_PATCH_UPLOAD_ACK
Code:
1   byte    result
Step 7.

GlobalManager will request the the files that are supposed to be uploaded via 0x6004 - FRAMEWORK_FILE_TRANSFER_REQ
Code:
4   uint    file.ID
4   uint    fileOffset  // Used to continue interupted downloads from last chunk. (can be ignored)
You're now supposed to send 0x1001 - NETENGINE_FILE_DATA
Code:
*   byte[]  data    // up to 4090 bytes of raw file data
until the file is complete then you send 0xA004 - FRAMEWORK_FILE_TRANSFER_ACK
Code:
1   byte    result
if(result == 0x02)
{
	1	byte	errorCode
}
GlobalManager will also send 0x3101 - SM_MODULE_PATCH_NOTIFY_PROGRESS telling you what's going on. (optional)
Code:
1   byte    notifyFlag                          //1 = Relay, 2 = Recording database
if(notifyFlag & 1)
{
    1   byte    state   // 1  = Start, 2 = Progress
    if(state == 2)
    {
        1   byte    fileCount
        1   byte    fileCurrent
    }
}
if(notifyFlag & 2)
{
    1   byte    state   // 1  = Start, 2 = Progress
    if(state == 2)
    {
        1   byte    progress // 0-100
    }
}
Repeat Step 7. until GlobalManager sends 0x3102 - SM_MODULE_PATCH_NOTIFY_COMPLETE
Code:
1   byte    result  
if(result == 2)
{
    1   byte    errorCode
    // 1 = patch failed: relay server offline
    // 2 = patch failed: fail to tranfer patch data to relay server
    // 3 = patch failed: service operating
    // 4 = patch failed: recording db failed
}
Step 8. Since you're automating stuff make sure you put the front servers back into service

0x7008 - SM_CONTROL_SERVICE_START_REQ
Code:
1   byte    ServiceMode     // 1 = Start, 2 = Stop
2   ushort  ServerBodyID
Your users can now download the latest patches via Silkroad.exe as usual.

If you have questions just ask.
DaxterSoul is offline  
Thanks
8 Users
Old 10/27/2023, 10:31   #5
 
elite*gold: 0
Join Date: Sep 2011
Posts: 121
Received Thanks: 32
Quote:
Originally Posted by DaxterSoul View Post
Just using the thanks button would not be sufficient. This is pure gold. Thanks a lot!
thehaifisch is offline  
Old 10/29/2023, 01:31   #6
 
elite*gold: 100
Join Date: Sep 2017
Posts: 1,109
Received Thanks: 903
Quote:
Originally Posted by DaxterSoul View Post
...
Had some of these parsed years ago, but most were incomplete.

Thanks a bunch dude.
#HB is offline  
Reply


Similar Threads Similar Threads
vSRO module messages to file instead of window?
09/01/2021 - SRO PServer Questions & Answers - 2 Replies
Hi everyone, Is it possible to modify vsro server modules to write all messages into FatalLog files instead of the module window? It would be lovely as one could read all messages remotely without having to login interactively. Sorry if it has been asked already or shared before, I couldn't find any info. Cheers
SMC Error Module Patch
02/02/2019 - SRO Private Server - 2 Replies
Hello, when i try to patch my SR_Client in ModulePatch i get this error: patch failed: recording db failed I added my IP in ServiceManager, smc_updater! Any ideas?
patch patch patch patch patch patch patch
04/14/2011 - CrossFire - 3 Replies
http://images1.memegenerator.net/ImageMacro/599994 0/LIKE-A-BOSS.jpg



All times are GMT +1. The time now is 17:30.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.