it's time for another ( @ronz007 ). I've been asked quite often: "Can you change the 'Create Button' to lead directly to character creation?". I've had no viable solution for this, yet. But let's change that now.
Switching between states
Silkroad's internals is split into so different states. Joymax calls these states processes. Each process is represented by a single class. CPSCharacterSelect is the process showing all the characters. CPSCharacterCreateEurope is the process for creating an european character and CPSCharacterCreateChina is the equivalent for chinese characters.
The game will only run one process which is comprehensibly since the game can only have one state at a time. There are two different ways to change the state:
* Create a new process and replace the current one
* Create a child process and pause the current one
The character selection is made up of different states, too. We distinquish between transitional states and static states. Transitional states are run once, before entering or after leaving a static state. The transitional-state for leaving the character selection and entering the character creation looks like this:
The two creation-processes are run as child processes. My best guess is, that completely switching over to either CPSCharacterCreateEurope or CPSCharacterCreateChina will litereally kill CPSCharacterSelect and therefore lose the network session and require a re-login. After creating a character, we will return to CPSCharacterSelect, so we need that process again, anyways.
So thats how we change to the creation of a character: Use a child process!
Finding the button handler
Lets investigate a little on where to make a change. Silkroad's UI event handling is quite weird. The control-id plays a big role in this.
Since Joymax were just a bunch of thieves .. EH!? ... I mean they got inspired from using MFC!, we just can look up how message handlers work in the MFC ... (oh, you can't imagine how long I reversed the MFC without noticing it's the MFC, again!!!).
With a bit of magic and a snap with your finger, you'll end up with the OnCreateButton_Click-handler being at 0x0085DE50. Swing your wand and smack your head on the keyboard to extract the pseudocode for this function:
Believe it or not, that's part of my workflow. If you don't have your wand with you, you can also search for the text-string shown in the pseudocode.
Do it!
So we're done now. We know where things happen. We know how things happen. So lets actually do it.
Lets wrap things up. We need to change the button handler to:
* Set the global g_selected_idol to CHINA (1)
* Set the state of CPSCharacterSelect to *leave for character creation* (9)
* Hope we did everything right.
Put all the ingredients in your bubbling cauldron, add a spoon of oldschool-player-tears and two cups of pulverized silkroad money. Give it a pretty good stirr. Okay. Done.
Since most of you got confused by using C++ code, I will switch back to good old assembly for this one, eventho C++ would have been way more fun.
Code:
// g_selected idol is at 00EC2D64
mov dword ptr [00EC2D64], 1
// current_state is a member of the current object at offset 0xE4
// usually, this is referenced as ECX, but if the function gets bigger and has nested calls, ECX is transfered to ESI for simplicity reasons.
mov dword ptr [esi+E4], 9
Now where to put it?
We just have one problem: The instructions are too large . Both instructions are 10 Byte-instructions :/. We need to pad the epilogue.
i wouldnt say "useless" you can learn alot about the client infrastructure even while accomplishing this kind of a task.
nevertheless, i do think there might be something else to it, if you will.
Back in the days of iSRO (cap 60~80), when you would click "restart" when you are spawned in the worldserver already, you would be redirected to the char selection screen instead of the gatewayserver (login credentials screen), they did so for about quite a bit of a time (mby a few months), then they patched it back to the original one which is as it is now (looking back they reversed this change because it allowed people to be still connected to the worldserver, may i remind that back then without a premium gaining access to the server is a bit like teaching poetry to fish), knowing so, i tried to replicate the feature using my filter, with success but it had some problems due to the obvious limitation, it worked, but not perfectly for all of the users.
if you could think of a way to accomplish that old school feeling that would be great
hit me up on skype @ , if you want.
@eitai123 ; next time use mention rather than quoting a long thread.
Usage:
Quote:
Usage `[`mention=ID]value[/mention`]`
Example Usage `[`MENTION=687427]florian0[/MENTION`]`
Example Output @florian0;
Remove ` character
EDIT: IT seems ID parameter is a must. EDIT2 : I confirmed from a mod in discord that we can use mentioning just with typing @Username. forum will parse it correctly.
Back in the days of iSRO (cap 60~80), when you would click "restart" when you are spawned in the worldserver already, you would be redirected to the char selection screen instead of the gatewayserver [...]
I think I can "simulate" that with CPSQuickStart. CPSRestart could lead to CPSQuickStart instead of CPSTitle. You just need to grab the login credentials somehow ... It shouldn't need serverside modifications as long as the server is not "Crowded". Then you'll need some kind of privileged login for this char ...
I think I can "simulate" that with CPSQuickStart. CPSRestart could lead to CPSQuickStart instead of CPSTitle. You just need to grab the login credentials somehow ... It shouldn't need serverside modifications as long as the server is not "Crowded". Then you'll need some kind of privileged login for this char ... maybe keep the session open in the filter and just reattach it ...
I just figured something out: Those lazy devs at Joymax actually left the old behaviour of the button in the client. Its not even disabled, just skipped.
Code:
void CPSCharacterSelect::TriggerAnimation_ToIdolBox()
{
// Fade Buttons and Text for idol selection
m_ifbuilder.GetGUIObjectByID(PSCHARSEL_GDR_STA_TITLE, 1)->Fade(0, 5.0, 0.0, 1);
m_ifbuilder.GetGUIObjectByID(PSCHARSEL_GDR_STA_REGIONTITLE, 1)->Fade(255, 5.0, 0.0, 1);
m_ifbuilder.GetGUIObjectByID(PSCHARSEL_GDR_BTN_CREATE, 1)->Fade(0, 0.5, 0.0, 1);
m_ifbuilder.GetGUIObjectByID(PSCHARSEL_GDR_BTN_BACK, 1)->Fade(0, 0.5, 0.0, 1);
m_ifbuilder.GetGUIObjectByID(PSCHARSEL_GDR_BTN_CANCEL, 1)->Fade(255, 0.5, 0.0, 1);
m_ifbuilder.GetGUIObjectByID(PSCHARSEL_GDR_BTN_NEXT, 1)->Fade(0, 0.5, 0.0, 1);
m_ifbuilder.GetGUIObjectByID(PSCHARSEL_GDR_BTN_PREV, 1)->Fade(0, 0.5, 0.0, 1);
// Fade name-change stuff
for (int i = 0; i < ARRAY_SIZE(namechange_ids); ++i)
{
m_ifbuilder.GetGUIObjectByID(namechange_ids[i], 1)->Fade(0, 0.5, 0.0, 1);
}
// Preselect Idol
g_selected_idol = 1;
// Set state to leave for character creation
current_state = 9;
// Clear keyframes
m_cameraworking->sub_4E6630();
// Add keyframes to camera path.
// Note: These are the same keyframes as you would
// have pressed the "Cancel" Button and leave
Keyframe* current_frame = &frames_intro[0];
for (int i = ARRAY_SIZE(frames_intro) - 1; i >= 0; --i, ++current_frame)
{
m_cameraworking->AddKeyframe(i * 2, current_frame->translation, current_frame->rotation);
}
theApp.camera.character = m_cameraworking->location;
theApp.camera.rotation_to_world = m_cameraworking->rotation;
theApp.camera.zoom = m_cameraworking->zoom;
m_cameraworking->float_F0 = 2.0;
// Fade to black
m_ifbuilder.GetGUIObjectByID(PSCHARSEL_GDR_FADE, 1)->sub_6526E0(0, 255, 0.5, 0.0, 1);
// Clear keyframes (RIP animation :/ )
m_cameraworking->sub_4E6630();
// Add keyframes to camera path.
// Note: These keyframes lead to the box
for (int i = 0; i < ARRAY_SIZE(frames_box); ++i)
{
m_cameraworking->AddKeyframe(i * 5.0 / 3.0, frames_box[i].translation, frames_box[i].rotation);
}
theApp.camera.character = m_cameraworking->location;
theApp.camera.rotation_to_world = m_cameraworking->rotation;
theApp.camera.zoom = m_cameraworking->zoom;
m_cameraworking->float_F0 = 5.0;
// Assign state for viewing the box
current_state = 7;
// Confirm state-change
sub_862410(1);
}
As you can see, it's preparing to leave for Character Creation, but then just overrides everything and goes straight to the box.
Community challenge? Task: Place the correct JMP to skip the second animation Reward: Glory and honor
it's time for another "ussles" release ( @ronz007 ). I've been asked quite often: "Can you change the 'Create Button' to lead directly to character creation?". I've had no viable solution for this, yet. But let's change that now.
Silkroad's internals is split into so different states. Joymax calls these states processes. Each process is represented by a single class. CPSCharacterSelect is the process showing all the characters. CPSCharacterCreateEurope is the process for creating an european character and CPSCharacterCreateChina is the equivalent for chinese characters.
The game will only run one process which is comprehensibly since the game can only have one state at a time. There are two different ways to change the state:
* Create a new process and replace the current one
* Create a child process and pause the current one
The character selection is made up of different states, too. We distinquish between transitional states and static states. Transitional states are run once, before entering or after leaving a static state. The transitional-state for leaving the character selection and entering the character creation looks like this:
The two creation-processes are run as child processes. My best guess is, that completely switching over to either CPSCharacterCreateEurope or CPSCharacterCreateChina will litereally kill CPSCharacterSelect and therefore lose the network session and require a re-login. After creating a character, we will return to CPSCharacterSelect, so we need that process again, anyways.
So thats how we change to the creation of a character: Use a child process!
Finding the button handler
Lets investigate a little on where to make a change. Silkroad's UI event handling is quite weird. The control-id plays a big role in this.
Since Joymax were just a bunch of thieves .. EH!? ... I mean they got inspired from using MFC!, we just can look up how message handlers work in the MFC ... https://msdn.microsoft.com/en-us/library/0x0cx6b1.aspx (oh, you can't imagine how long I reversed the MFC without noticing it's the MFC, again!!!).
With a bit of magic and a snap with your finger, you'll end up with the OnCreateButton_Click-handler being at 0x0085DE50. Swing your wand and smack your head on the keyboard to extract the pseudocode for this function:
Believe it or not, that's part of my workflow. If you don't have your wand with you, you can also search for the text-string shown in the pseudocode.
Do it!
So we're done now. We know where things happen. We know how things happen. So lets actually do it.
Lets wrap things up. We need to change the button handler to:
* Set the global g_selected_idol to CHINA (1)
* Set the state of CPSCharacterSelect to *leave for character creation* (9)
* Hope we did everything right.
Put all the ingredients in your bubbling cauldron, add a spoon of oldschool-player-tears and two cups of pulverized silkroad money. Give it a pretty good stirr. Okay. Done.
Since most of you got confused by using C++ code, I will switch back to good old assembly for this one, eventho C++ would have been way more fun.
Code:
// g_selected idol is at 00EC2D64
mov dword ptr [00EC2D64], 1
// current_state is a member of the current object at offset 0xE4
// usually, this is referenced as ECX, but if the function gets bigger and has nested calls, ECX is transfered to ESI for simplicity reasons.
mov dword ptr [esi+E4], 9
Now where to put it?
We just have one problem: The instructions are too large . Both instructions are 10 Byte-instructions :/. We need to pad the epilogue.
/* #ifdef MAX_CODE int regionType = 0 switch(regionType) { case COUNTRY_CHINA: //0x00 g_SelectedRegion = CHINA; //1 m_pGfxMainFrame->SetProgressPos(0); CreateProcess(GFX_RUNTIME_CLASS(CPSCharacterCreateChina)); m_pGfxMainFrame->SetProcess(GetChildProcess()); break; case COUNTRY_EUROPE: ///0x01 g_SelectedRegion = EUROPE; //0 m_pGfxMainFrame->SetProgressPos(0); CreateProcess(GFX_RUNTIME_CLASS(CPSCharacterCreateEurope)); m_pGfxMainFrame->SetProcess(GetChildProcess()); break; default: OnRegionMovein(); break; #else // before the client call the this hook it up and pass one of the cases either 0x00 for china or 0x01 for europe // g_nSelectedRegion OnRegionMovein(); #endif */ }
Hey buddy, why don't you set the value to one of either cases like 0 or 1 that's represents the type of region you want to create character for.
I wanted to do that. I even had that solution prepared. But people told me they have a hard time finding Visual Studio 2005 (+DirectX SDK) for compiling, so I decided to do a "mini-edit" with assembly this time.
Setting g_SelectedRegion (g_selected_idol @ 0x00EC2D64) to china (1) and changing the state to "after clicking on an idol" seemed to be the easiest way. Isn't that similar to what you're suggesting?
I wanted to do that. I even had that solution prepared. But people told me they have a hard time finding Visual Studio 2005 (+DirectX SDK) for compiling, so I decided to do a "mini-edit" with assembly this time.
Setting g_SelectedRegion (g_selected_idol @ 0x00EC2D64) to china (1) and changing the state to "after clicking on an idol" seemed to be the easiest way. Isn't that similar to what you're suggesting?
[Buying] """""PUBG Key"""""""" 09/28/2017 - PlayerUnknown's Battlegrounds Trading - 5 Replies Moin,
ich suche noch einen Key von PUBG.
Bezahle per PP.(kein Family& Friends)
Nur mit RAT!
mfg
:mofo: