Jump to content

Amun

Contributor
  • Posts

    199
  • Joined

  • Last visited

  • Days Won

    1
  • Feedback

    100%

Posts posted by Amun

  1. The images aren't working. If you want some help, explain the problem properly, don't just say "I have a problem".

     

    Is it showing the wrong stones? Is the text fucked up? Is it not showing items? Is it showing extra items?

    Like, what's the problem?

     

    What I understood from your first message is that it shows a casting speed stone which shouldn't be there. Correct me if I'm wrong.

     

    Anyhow, if you want to get rid of the stones drop, just remove them from constants, like TMP said.

  2. Hello, good people!

     

    I was writing something to validate the server data(like blend.txt, cube, etc) and stumbled upon this lovely comment:

    Quote

    // Choong Ki-hwan's probability table
    // It would be neat if we fix it so that it also receives the probability from blend.txt
    // by rtsummit

    So then I asked myself "Why not?" 🙂

    Anyhow, here's the code(everything is in blend_item.cpp):

    // after the last #include, add
    #include <random>
      
    // Optional: You can add this after the last import if you want.
    // I've replaced the "Token" thing because Visual Studio was playing tricks with the tabs and it was too annoying.
    #define str_match(s1,s2) _stricmp(s1,s2)==0
    // or, if you want, you can just completely replace the Token stuff, like I did. Up to you, it's just optional stuff..
    
    // Anyhow, now edit this struct:
    struct BLEND_ITEM_INFO
    {
    	DWORD	item_vnum;
    	int		apply_type;
    	int		apply_value[MAX_BLEND_ITEM_VALUE];
    	int		apply_duration[MAX_BLEND_ITEM_VALUE];
      
      // add these
    	int     apply_prob[MAX_BLEND_ITEM_VALUE];
    	int     duration_prob[MAX_BLEND_ITEM_VALUE];
    	int     apply_prob_sum;// we'll just do the sum straight away
    	int     duration_prob_sum;// since we have to check if it has probability or not
    };

     

    // search for
    static int FN_random_index()
    
    // add these before(or after.. whatever)
    // You don't really have to add this, you can just use number(min, max) if you want to
    int Randomi(int minx, int maxx) {
    	std::random_device rd; // obtain a random number from hardware
    	std::mt19937 gen(rd()); // seed the generator
    	std::uniform_int_distribution<> distr(minx, maxx); // define the range
    
    	return distr(gen);
    }
    
    int RandomFromProbs(int probs[], int probsSum)
    {
    	int rand = Randomi(1, probsSum);
    	int accumulated = 0;
    	
    	for (int i = 0; i < MAX_BLEND_ITEM_VALUE; i++)
    	{
    		// this is just a fallback in case someone puts 0 for all of them
    		// or maybe we should call FN_random_index from here instead?
            // up to you..
    		if (i == MAX_BLEND_ITEM_VALUE - 1)
    			return i;
    
    		// if the probability is 0, then it's disabled, skip it
    		if (!probs[i])
    			continue;
    
    		accumulated += probs[i];
    		if (rand <= accumulated)
    			return i;
    	}
    }

     

    // search for 
    else Token("end")
    
    // Add this before
    // if you didn't add that define, change these to Token
    // here: else Token("apply_prob")
    // and the second one: else Token("duration_prob")
    
    		else if (0 == strcmp(key, "apply_prob"))
    			{
    				for (int i = 0; i < MAX_BLEND_ITEM_VALUE; ++i)
    				{
    					v = strtok(NULL, delim);
    					if (!v)
    					{
    						fclose(fp);
    						return false;
    					}
    
    					blend_item_info->apply_prob_sum += std::stoi(v);
    					str_to_number(blend_item_info->apply_prob[i], v);
    				}
    			}
    			else if (0 == strcmp(key, "duration_prob"))
    			{
    				for (int i = 0; i < MAX_BLEND_ITEM_VALUE; ++i)
    				{
    					v = strtok(NULL, delim);
    					if (!v)
    					{
    						fclose(fp);
    						return false;
    					}
    
    					blend_item_info->duration_prob_sum += std::stoi(v);
    					str_to_number(blend_item_info->duration_prob[i], v);
    				}
    			}

     

    // Search for
    bool	Blend_Item_set_value(LPITEM item)
    
    // Inside look for:
    			if (item->GetVnum() == 51002) // energy crystal
    			{
    				apply_type = blend_info->apply_type;
    				apply_value = blend_info->apply_value[FN_ECS_random_index()];
    				apply_duration = blend_info->apply_duration[FN_ECS_random_index()];
    			}
    			else
    			{
    				apply_type = blend_info->apply_type;
    				apply_value = blend_info->apply_value[FN_random_index()];
    				apply_duration = blend_info->apply_duration[FN_random_index()];
    			}
    
    
    // Comment them or just replace them with this:
    			apply_type = blend_info->apply_type;
    
    			if (blend_info->apply_prob_sum)
    			{
    				apply_value = blend_info->apply_value[RandomFromProbs(blend_info->apply_prob, blend_info->apply_prob_sum)];
    			}
    			else
    			{
    				if (item->GetVnum() == 51002) // energy crystal
    					apply_value = blend_info->apply_value[FN_ECS_random_index()];
    				else
    					apply_value = blend_info->apply_value[FN_random_index()];
    			}
    
    			if (blend_info->duration_prob_sum)
    			{
    				apply_duration = blend_info->apply_value[RandomFromProbs(blend_info->duration_prob, blend_info->duration_prob_sum)];
    			}
    			else
    			{
    				if (item->GetVnum() == 51002) // energy crystal
    					apply_duration = blend_info->apply_duration[FN_ECS_random_index()];
    				else
    					apply_duration = blend_info->apply_duration[FN_random_index()];
    			}

     

    That's it, you're good to go.

    I should mention that I didn't try it on the live server, just in the validation app, but everything should work just fine.

     

    Example usage:

    # this is just to prove that you don't have to add the probability stuff in all of them
    # you can just add where you want to
    #Blue Dew
    section
    	item_vnum	50825
    	apply_type	ATT_BONUS
    	apply_value	30	50	70	90	120
    	apply_duration	60	120	180	300	600
    end
    
    #white dew
    section
    	item_vnum	50826
    	apply_type	DEF_BONUS
    	apply_value	40	70	100	150	200
    # you can also add values like 0 1000 20 500 0
    # it will just ignore the 0 and do the math for the other ones
    	apply_prob	0	1000	200	150	90
    # if you have something like this it will ignore the 0 
    # and just give the one with a "valid" probability(the fifth, in this case - apply_value 200)
    #	apply_prob 0 0 0 0 1
    	apply_duration	60	120	180	300	600
    	duration_prob	1	2	3	4	5
    end
    
    #energy crystal
    section
    	item_vnum	51002
    	apply_type	ENERGY
    	apply_value	1	3	5	7	10
    	apply_duration	7200	7200	7200	7200	7200
    # and you don't have to add both probabilities(for duration and apply), you can just use one.. or none!
    	apply_prob	10	50	10	20	10
    end

     

    Have fun and let me know if you have any problems with it!

    Cheers!

     

    • Metin2 Dev 5
    • Good 3
  3. This is the hidden content, please

    Metin2 Download

     

    First of all, sorry if it's the wrong section, but I didn't know where else to write this.

    Right. For whoever's looking for a copy-paste tutorial, keep looking, because this isn't the one.

    Also, if you're not sure if you should update it or not, you probably shouldn't.

     

    What's up with the files?

    They contain the data from the latest proto posted by P3ng3r(V22.0.8) + some of my thoughts from when I updated my own protos.

    I've also thrown in some last minute stuff(like the tables), just to make your life a little easier.

     

    What do you have to do?

    • Server:
    1. Update ProtoReader.cpp/ProtoReader.h(if you add the masks)
    2. Create/Update the tables in tables.h
    3. Create/Update the enums from item_length.h and length.h
    4. Update ClientManagerBoot if your client is either using or mirroring the text files to MySQL
    5. Again, if you're reading the proto from MySQL, you'll have to update item_proto and mob_proto tables

     

    • Client:
    1. Update the enums from ItemData.h(+ItemData.cpp if you'll create functions for the masks)
    2. If you know you're going to use the new types and applys in the client, update PythonItemModule.cpp as well

     

    • DumpProto:
    1. Update dump_proto.cpp, ItemCSVReader.cpp/h with the new values

     

     

    If you're going to use all the apply values, change BYTE to WORD in SItemApply and update all the functions/packets connected to it accordingly, otherwise it'll overflow and fuck up your  whole server.

     

    Is this everything you need? I would say yes.

    Do I give a shit if you fuck up? No.

     

    Links:

    Mob Data:
    https://mega.nz/file/FPwDiawD#TyhKbO0aAqHcJK0OcxQkGTUITr__jCeji4XRXOR0qPI
    
    Proto Data:
    https://mega.nz/file/0CA3iKSS#12gZ-t3NnB3tOnSWR7gH8OdvmfoH6I3xN_ZgJz_cUKU

    Virus Total:

    Proto Data
    https://www.virustotal.com/gui/file/d889071c36bee9c03022d4946efbf7e08aa12699aa21f64a2e55bd538b8adcc4?nocache=1
    
    Mob Data:
    https://www.virustotal.com/gui/file/6d80064dad2fbe48b9b21d3de6f7b4c4529e7d93911e4cb4859c9da69ea16595?nocache=1

     

    I'd like to thank @ xP3NG3Rx for all the work he puts into unpacking and reversing functions from the official servers.

    We wouldn't be here without you, mate. Thank You!

     

    Good luck!

     

    Edit 15.09.2022:

    Sorry to bump this, but someone asked about it in Q&A, so here's the source for dump_proto with the data already updated.

    VS 2022, I have not tried with other versions. I should've clean it up, but whatever.. who tf has time for that..

    This is the hidden content, please

     

    Have a great day,

    - Amun

    • Metin2 Dev 117
    • Eyes 2
    • Dislove 2
    • Angry 1
    • Not Good 1
    • Think 2
    • Confused 1
    • Good 36
    • Love 8
    • Love 58
  4. 2 minutes ago, BroccoloMaestro said:

    @ TMP4 ur client is v22? meaning have everything update?
     

    https://metin2.dev/board/topic/15649-official-unpacked-updates-metin2-new-spam-free/page/3/?tab=comments#comment-136592

     

    if not, i need to unpack and pack all the updates since 2017? or i can implement only the news updates?

    What date is the last update of this client? If you can give me the exact date from which I have to start patching I would be grateful!

    What he means by 2022 is that the client's source can be compiled with Visual Studio 2022.

    The Client is from 2013/2014.

    Updating the client to the latest official files require changing the proto structures as well, for both item and mob_proto, since they're not compatible. You'll have to add the new types, subtypes, applys, maskType, maskSubtype, as well as the columns for 67Material and elemental shit.

  5. Spoiler
    46 minutes ago, BroccoloMaestro said:

    first of all you should calm down and be more politically correct.

    Second thing I said that it worked even without having compiled the client as far as the inventory is concerned but after that I compiled the client and the problem does not concern the compilation of the v22 client but the files present in ETC which may be missing.

    third are the files present in the extra pack (exstesion pack) and I am sure I have not done anything wrong, it simply asks me for the files in the folder etc that when I do the pack it does not have them. then maybe I repeat I'm wrong, but certainly these are not the ways of speaking.

     

    Fourth, how do I "screw" the packs when both inventory 4 and 6thskill have nothing to do with cursor? I just edited all the files that needed to be changed and then used the patcher.
    I took the ETC folders present in the two rars and put them in a single folder etc, made the pack and uploaded in pack. I can also be wrong but surely since I do not have the original folder etc by overwriting the files etc in the pack I have done some damage, precisely for this reason I am wondering what I am doing wrong.

     

    Thanks for your comments but I prefer to wait @ TMP4 which unlike you, even if a person is stupid, he still helps you without being so rude.

    I wish you good continuation and I hope to see you never again :D

     

    P:S:
    ah since you say you do not need to follow any discussion, rightly you do not know that @ TMP4 has no problem providing assistance directly on this post, and if you do not believe me look at some previous message / comment its via HIDE tag where it tells me that is not gonna provide discord assistance but have no problem helping out here. since all the questions so far are always inherent to its release. Please keep reading nothing and be so aggressive that you solve something: D

     

    I think i solve the problem, i need first to unpack the folders i need then put the files and then pack everyyhing again.

    @ TMP4 let me know if im right! But i think this should be the solution, i forget this step, but now i got how u can get those foders! i feel so stupid right now >_<

     

    If you've created a new folder, don't forget to also add it in `Index`.

     

    In regards to unpack/repack, yes, but only the first time. If you already have the folder unpacked, there's no point to unpack it again, just add your files, repack it and move them to `pack`.

     

    One workaround to avoid waiting half an hour when working in big directories is to just add them straight to the root folder.

    What do I mean by this? Let's say, for example, that you want to add some new stuff in the `PC` archive. Instead of unpacking the entire folder(which is huge) and repacking it again, just create a `ymir work` folder in root and add your files.

    After you've tested and everything works properly, you can move them to the proper directory(PC).

     

    I don't mind helping people(I quite enjoy it, actually), but I get fucking pissed when I want to read something about some files(like, for example, if any new bugs came out) and have to go through 1000 messages of people having off topic discussions. We have a `Questions & Answers` section for a reason.

    I hope you understand what I mean.

  6. 2 minutes ago, BroccoloMaestro said:

    I don't know.. i repacked again, but the problem is that none of the files for inventory4 and skill6th keep files inside the cursor, and it could also be an error due to the compilation of the v22 client ... but the error is clear it cannot load that file, and in my opinion it is a missing file of this client, but maybe I can be wrong,, i will waiting for @ TMP4 for further instructions.

    That sub is used in the mouseModule and it is NOT missing so Filachilla was probably right, you fucked up the packs.

     

    Now, regarding what you said earlier, no, I shouldn't have followed any fucking discussion. This topic is about what TMP posted and any questions/discussions about custom implementations/modifications of the currently posted files are off topic and should be discussed in `Discussions` or https://metin2.dev/forum/35-questions-answers/

     

    Also, as a matter of fact, yes, I did read a bit about what you said about the inventory - you said you've only changed the client part without compiling the source, which doesn't make any sense since the capacity of the inventory is actually set from the source.

  7. 13 minutes ago, BroccoloMaestro said:

    Is any file missing? after extraction of etc and then pack and then in folder pack i got this error:

     

    wich is tell me that cannot find that .sub file, do u know where can i get it? or im missing something?

    You should've probably looked if you have that file before asking a question here and waiting for an hour for someone to answer.

    I've tested the client and didn't have any problems. Not in regards to the files, at least.

  8. I recommend you give up on whatever you're trying to do with metin2 and start learning some basic programming. I don't say that to bash on you, but giving you some advice.

     

    The error states clearly that the function `CompressEncryptedMemory` does not take 5 arguments.

    Why? Well, if you would've taken the time to look in EterBase/lzo.cpp, you would've seen that the function actually takes only 4 arguments.

    bool CLZO::CompressEncryptedMemory(CLZObject & rObj, const void * pIn, UINT uiInLen, DWORD * pdwKey)
    {
        rObj.BeginCompress(pIn, uiInLen);
    	
        if (rObj.Compress())
        {
    		if (rObj.Encrypt(pdwKey))
    			return true;
    		
    		return false;
        }   
    	
        return false;
    }  

    The same with `Decompress` function - it doesn't take 4, but 3 arguments.

     

    Good luck

  9. On 3/31/2022 at 2:41 PM, Filachilla said:

    @ TMP4 I found some mistakes made by ymir..  You can fix it^^

    1. Open notepad++ and in extended search type: ;; (in some codes are 2x ;; I think 3-4x.. So you can delete one ; from code -> just check code with notepad++ and you found it=)

    2. I found in ProtoReader.cpp little mistake with mob size values... Here is type SMALL, MEDIUM, BIG, but! Ymir made mistake and write here SAMLL (dont forgot change mob_proto too + dump_proto)

    3. This is not mistake but, in ProtoReader.cpp is antiflag ANTI_MUSA, ANTI_ASSASSIN, ANTI_SURA, ANTI_MUDANG.. (I think ANTI_WARRIOR -> original ANTI_MUSA, and ANTI_SHAMAN -> original ANTI_MUDANG  looks better.. So you can too change it.. Too dont forgot change item_proto, dump_proto..

    4. HEADER_GC_SEPCIAL_EFFECT (HEADER_GC_SPECIAL_EFFECT -> dont forgot change all valid functions code..)

    5. Search with extended search word "pakcet" in sources.. (packet, dont forgot change all valid code..)

    6. const DWORD c_Equipment_Belt  = c_New_Equipment_Start + 2;; (double ;;, check client its more time same mistake..)

    7. UserInteface.cpp

    this under NANOBEGIN:
    
    #ifdef _DISTRIBUTE 
    		stRegisterDebugFlag ="__DEBUG__ = 0";
    #else
    		stRegisterDebugFlag ="__DEBUG__ = 1"; 
    #endif
    
    to:
      
    #ifdef _DEBUG 
    		stRegisterDebugFlag ="__DEBUG__ = 1";
    #else
    		stRegisterDebugFlag ="__DEBUG__ = 0"; 
    #endif


    8. in ENGLISH item_proto are 2x [SPACE] in some items name.. For Example: Misfortune Armour, Stone of Monsters+7 etc..

    Edit: If I found something more I update this post.. Btw. Maybe I can release extended revision of this file with more corrections.. (translate lc_text to english, minilzo to lzo, removed auction, passpod, openid, netmarble, sms, mobile, sim, billing, xtrap, hackshield, pcbang, auth_brazil, brazil locale, fucking_brazil potions, server_check, limit_time, unittest, gtest, teen_packet, repaired tables in db, models, so just extended version of this file more clean.

    First, thank you for the contribution, I'm sure it's in good faith!

    Now, let's clarify some things before anyone starts doing what you said.

    1. The ";;" things doesn't change anything. You can basically put ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;" and it's the same shit, it'll just be ignored.

     

    2. Yes, SAMLL could cause problems. Though, if it would've been used in the proto, you wouldn't be able to start the server because of it(Correct me if it is used now, since I didn't bother checking it).

     

    3. Changing ANTI_MUSA to ANTI_WARRIOR and ANTI_MUDANG to ANTI_SHAMAN is going to force you to edit the whole proto. Is this a big task? No. Will you have to do it everytime you change the proto with, let's say, the proto P3ng3r gives us all the time in the unpacked official files? Yes. Should you change it? Up to you. I don't like extra work.

     

    4. & 5. Changing that header/packet doesn't change anything.

     

    6. see 1.

     

    7. That's the same exact shit. Just because you have "release" mode available in the source, it doesn't mean you should use it.

    Notes:

    Debug: used for debugging.

    Release: The version is stable and released for INTERNAL use.

    Distribute: The version is stable and can be distributed to the rest of the world.

    It's confusing, I know. Apple came up with this for their software and the rest of the world had to follow(why? I don't know and I don't give a shit).

     

    8. Again, that doesn't change anything. It just adds more shit to keep track of when changing the proto with different files.

     

    Don't take this the wrong way, I really appreciate when people contribute to the community, but maybe next time tell the others(who maybe don't know better), whether what they're changing is going to help them in any way or if it's just optional stuff that doesn't make no difference(or actually give them more stuff to keep track of in the future).

     

    If you want to post that source, post it, no one's stopping you. I might actually help someone, if that's your intent.

     

    Thank you and have a great day!

  10. I don't have the "system"(just wanted to mention this from the beginning) so don't ask for code(nor examples, for that matter).

    I'm probably too late here, but why don't you just attach it to the character window?

    OR

    Get the position of the character window when you click the button and update the position of the bonus window before it shows up.

     

    Good luck

  11. On 3/10/2022 at 1:11 PM, EnneGi said:

    Client in release/distribution mode, db/game server in release to reproduce the bug.

    I tried db/game in debug mode, and client still in release/distribution and it works

    Thanks!!

    Apologies for the late reply, I didn't have a lot of time for metin2.

     

    Now, in regards to the bug, I remembered about a conversation I had with @MrQuin in Dec 2020 and he said he had a similar problem when running the server in release mode on windows.

     

    I've just compiled the server with this and seems like it's fixed now.

    In common/tables.h search for:

    typedef struct SPlayerSkill

     

    And replace it with:

    typedef struct SPlayerSkill
    {
    	BYTE    bMasterType;
    	BYTE    bLevel;
    #ifdef _WIN32
    	DWORD    tNextRead;
    #else
    	time_t    tNextRead;
    #endif
    } TPlayerSkill;

     

    I'll upload the source with the update when I have a bit of free time.

    Thank you for letting us know!

     

    For everyone else:

    Please don't hesitate to write a comment or shoot me a message if you find any other bugs!

    Thank You!

     

    Here's a picture of the server running in release:

     

    https://metin2.download/picture/Wm8fP1eA7eiz6Q7tbSp17lwWCH097CJL/.png

     

    Problem update: 17/01/2023

    Just found out(by mistake) it happens because `_USE_32BIT_TIME_T` preprocessor definition is only added in debug build. To fix it once and for all(no need to edit the tables anymore), do the following:

    Select all projects(game, db, gamelib, etc), right click -> properties -> C/C++ -> Preprocessor

    (note: make sure the configuration is set for `Release`)

    Extend preprocessor definitions with `_USE_32BIT_TIME_T`

    • Love 1
  12. 9 minutes ago, EnneGi said:

    Really thanks for the tips. I'm working on it, if i found the root cause i will post it.

    Meanwhile, i found that this bug happens only in Release mode compilation with Windows. In debug mode, it just works out of the box, Skill points are setted. OBV this bug doesn't happen if you compile TMP4 source in freebsd.

    To summarize, it is reproducible only if you compile these source in Windows via Visual Studio in Release Mode - 32 bit.

    I'm compiling right now. I'll take a look once it's done.

     

    Does it happen when both the client and the server are running in release?

    Or when only one of them is running in release while the other is in debug?

  13. 9 hours ago, duwen123 said:

     

    Hello! Sorry for my late response! 😇

     

    I encounter a problem, sadly. These are the steps that I followed:

    -> I created a new solution after which I added an existing project (as you can see in the picture below):

      Hide contents

    spacer.png

     

    -> After uploading, solution explorer looks like this:

      Reveal hidden contents

    spacer.png

     

    -> And when I open a file, for example affect.cpp, I get errors that say that certain files cannot be opened and certain macros, classes and functions are not recognized. (images below)

      Hide contents

    spacer.png

     

      Reveal hidden contents

    spacer.png

     

    So far I have only tried the game source.

    As far as I can tell, I think some libs should be included. Something like the binary source. 🤔

    That's not the only thing you have to do, mate. I assumed you have at least a basic understanding of VS.

    It'll take me a few hours to write it step by step and I will not do that.

     

    However, here's the basics of what you should do, just to get you started:

    Create projects for each lib as well(libgame, liblua, libpoly, libsql, libthecore) and link them to the extern.

    You should probably create a folder for Common as well(a folder, not a project!).

    Add the links for the extern to game as well(in case you didn't), then right click on the project->settings->linker->input and add all the libs to "Additional dependencies"

    Here's mine for the debug setup, to save you some time: mysqlclient.lib;ws2_32.lib;DevIL-1.7.8d.lib;DevILU-1.7.8d.lib;DevILUT-1.7.8d.lib;cryptlib.lib;libpoly_d.lib;libgame_d.lib;libthecore_d.lib;liblua_d.lib;%(AdditionalDependencies)

    Don't forget to add the links to where these libraries are in VS++ Directories-> External Include Directories and Library directories OR in Linker->General->Additional Library Directories !!!!

     

    These are just the things I remembered you have to do, but there's probably way more.

    I would've started with DB if I were you,. Game takes a while to compile and you'll rip you hair out if it fails 100 times.

     

    One other alternative would be to download some server files that are already set up and replace the files with yours. You can take a look at what I posted a few days ago if you want:

     

    Maybe I'll create a full tutorial on the forum at some point, but I'm too busy this week, so that's not going to happen very soon.

    • Not Good 1
    • Love 1
  14. Ok, so I'm past that.

    I've moved the initialization of modules in a separate function which is called before the python interpreter gets initialized(like the docs said).

    Now in UserInterface, Main(), the workflow looks like this:

    	if (LocaleService_LoadGlobal(hInstance))
    		SetDefaultCodePage(LocaleService_GetCodePage());
    
    	InitializeModules();
    	Py_Initialize();
    
    	CPythonApplication* app = new CPythonApplication;
    
    	app->Initialize(hInstance);

    Before the python app class is instantiated, we load the modules, then initialize the interpreter.

    Also, in PythonLauncher.cpp, I'm doing this(for now):

    CPythonLauncher::CPythonLauncher()
    {
    	if (!Py_IsInitialized()) {
    		Py_Initialize();
    	}
    }

    I should probably remove the initialization from here and just throw an error if it fails to initialize in UserInterface, but it's okay for now.. I have bigger fish to catch.

     

    Now, next problem(which is probably the last one in the source regarding this subject):

    In `UserInterface.cpp->RunMainScript()` we're calling 

    pyLauncher.RunFile("system.py")

    Which calls `CPythonLauncher::RunMemoryTextFile`

    Which calls `CPythonLauncher::RunLine` with the file data as a string.

    The problem is ```PyObject* v = PyRun_String((char*)c_szSrc, Py_file_input, m_poDic, m_poDic);``` always returns NULL instead of running the code.

    Yes, the code gets there, I've already checked.

     

    My thoughts are, it might be because of what's going on in RunMemoryTextFile, specifically in:

    	stConvFileData += "exec(compile('''";
    
    	// ConvertPythonTextFormat
    	{
    		for (UINT i = 0; i < uFileSize; ++i)
    		{
    			if (c_pcFileData[i] != 13)// carriage return
    			{
    				stConvFileData += c_pcFileData[i];
    			}
    		}
    	}
    
    	stConvFileData += "''', ";
    	stConvFileData += "'";
    	stConvFileData += c_szFileName;
    	stConvFileData += "', ";
    	stConvFileData += "'exec'))";
    	stConvFileData += '\0';

    The `compile()` function already takes method = 'exec', why do we need to call exec again?(see the first line in the code block before this)

    Here's the docs: https://docs.python.org/3/library/functions.html#compile

    If I keep it as `exec(compile(''' ` it always returns null when it's executed in RunLine and it throws a shitload of traceback errors.

    If I remove the `exec` and just `compile` it with the exec method passed in the function, it doesn't return null anymore, but the code doesn't run, it just returns and jumps straight to exit(0)(in user interface), so I assume the code doesn't get executed.

     

    I'll compile and post the errors in a few minutes.

    Any ideas?

    Here's the follow up:

    With `exec(compile(`:

    Spoiler

    0228 18:18:00158 :: Load system.py
    0228 18:18:00316 :: SYSERR: PyRun_String returned NULL. Tracing back...
    0228 18:18:02573 :: Traceback:

    Call: File "<string>", line 1, in <module>
    Call: File "system.py", line 1, in <module>
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 169, in __enter__
    Call: File "<frozen importlib._bootstrap>", line 987, in _find_and_load_unlocked
    Call: File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
    Call: File "<frozen importlib._bootstrap_external>", line 877, in exec_module
    Call: File "<frozen importlib._bootstrap>", line 233, in _call_with_frames_removed
    Call: File "D:\metin2\python3_branch\Client\lib\imp.py", line 1, in <module>
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 169, in __enter__
    Call: File "<frozen importlib._bootstrap>", line 987, in _find_and_load_unlocked
    Call: File "<frozen importlib._bootstrap>", line 233, in _call_with_frames_removed
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 169, in __enter__
    Call: File "<frozen importlib._bootstrap>", line 987, in _find_and_load_unlocked
    Call: File "<frozen importlib._bootstrap>", line 1053, in _handle_fromlist
    Call: File "<frozen importlib._bootstrap>", line 233, in _call_with_frames_removed
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 169, in __enter__
    Call: File "<frozen importlib._bootstrap>", line 1053, in _handle_fromlist
    Call: File "<frozen importlib._bootstrap>", line 233, in _call_with_frames_removed
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 169, in __enter__
    Call: File "<frozen importlib._bootstrap>", line 987, in _find_and_load_unlocked
    Call: File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
    Call: File "<frozen importlib._bootstrap_external>", line 877, in exec_module
    Call: File "<frozen importlib._bootstrap>", line 233, in _call_with_frames_removed
    Call: File "D:\metin2\python3_branch\Client\lib\importlib\util.py", line 1, in <module>
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 169, in __enter__
    Call: File "<frozen importlib._bootstrap>", line 987, in _find_and_load_unlocked
    Call: File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
    Call: File "<frozen importlib._bootstrap_external>", line 877, in exec_module
    Call: File "<frozen importlib._bootstrap>", line 233, in _call_with_frames_removed
    Call: File "D:\metin2\python3_branch\Client\lib\contextlib.py", line 1, in <module>
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 169, in __enter__
    Call: File "<frozen importlib._bootstrap>", line 987, in _find_and_load_unlocked
    Call: File "<frozen importlib._bootstrap>", line 921, in _find_spec
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 169, in __enter__
    Call: File "<frozen importlib._bootstrap>", line 987, in _find_and_load_unlocked
    Call: File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
    Call: File "<frozen importlib._bootstrap_external>", line 877, in exec_module
    Call: File "<frozen importlib._bootstrap>", line 233, in _call_with_frames_removed
    Call: File "D:\metin2\python3_branch\Client\lib\tokenize.py", line 1, in <module>
    Call: File "D:\metin2\python3_branch\Client\lib\io.py", line 60, in __getattr__
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 169, in __enter__
    Call: File "<frozen importlib._bootstrap>", line 987, in _find_and_load_unlocked
    Call: File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
    Call: File "<frozen importlib._bootstrap_external>", line 877, in exec_module
    Call: File "<frozen importlib._bootstrap>", line 233, in _call_with_frames_removed
    Call: File "D:\metin2\python3_branch\Client\lib\re.py", line 1, in <module>
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 169, in __enter__
    Call: File "<frozen importlib._bootstrap>", line 987, in _find_and_load_unlocked
    Call: File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
    Call: File "<frozen importlib._bootstrap_external>", line 877, in exec_module
    Call: File "<frozen importlib._bootstrap>", line 233, in _call_with_frames_removed
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "<frozen importlib._bootstrap>", line 169, in __enter__
    Call: File "<frozen importlib._bootstrap>", line 987, in _find_and_load_unlocked
    Call: File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load
    Call: File "D:\metin2\python3_branch\Client\lib\re.py", line 249, in compile
    Call: File "D:\metin2\python3_branch\Client\lib\re.py", line 288, in _compile
    Exception: File "D:\metin2\python3_branch\Client\lib\re.py", line 293, in _compile
    Call: File "D:\metin2\python3_branch\Client\lib\sre_compile.py", line 759, in compile
    Call: File "D:\metin2\python3_branch\Client\lib\sre_parse.py", line 937, in parse
    Call: File "D:\metin2\python3_branch\Client\lib\sre_compile.py", line 598, in _code
    Call: File "D:\metin2\python3_branch\Client\lib\sre_compile.py", line 71, in _compile
    Call: File "D:\metin2\python3_branch\Client\lib\sre_compile.py", line 71, in _compile
    Call: File "D:\metin2\python3_branch\Client\lib\re.py", line 249, in compile
    Call: File "D:\metin2\python3_branch\Client\lib\re.py", line 288, in _compile
    Call: File "D:\metin2\python3_branch\Client\lib\warnings.py", line 96, in _showwarnmsg
    Call: File "D:\metin2\python3_branch\Client\lib\warnings.py", line 20, in _showwarnmsg_impl
    Call: File "<frozen importlib._bootstrap>", line 1022, in _find_and_load


    0228 18:18:02579 :: SYSERR: RunMain Error
    0228 18:18:02597 :: SYSERR: CPythonApplication::Destroy

    So, the code gets executed but can't import anything?

    Here's system.py:

    Spoiler
    import sys
    import app
    import dbg
    
    sys.path.append("lib")
    
    class TraceFile:
    	def write(self, msg):
    		dbg.Trace(msg)
    
    class TraceErrorFile:
    	def write(self, msg):
    		dbg.TraceError(msg)
    		dbg.RegisterExceptionString(msg)
    
    class LogBoxFile:
    	def __init__(self):
    		self.stderrSave = sys.stderr
    		self.msg = ""
    
    	def __del__(self):
    		self.restore()
    
    	def restore(self):
    		sys.stderr = self.stderrSave
    
    	def write(self, msg):
    		self.msg = self.msg + msg
    
    	def show(self):
    		dbg.LogBox(self.msg,"Error")
    
    sys.stdout = TraceFile()
    sys.stderr = TraceErrorFile()
    
    #
    # pack file support (must move to system.py, systemrelease.pyc)
    #
    
    import marshal
    import imp
    import pack
    
    class pack_file_iterator(object):
    	def __init__(self, packfile):
    		self.pack_file = packfile
    		
    	def __next__(self):
    		tmp = self.pack_file.readline()
    		if tmp:
    			return tmp
    		raise StopIteration
    
    _chr = __builtins__.chr
    
    class pack_file(object):
    
    	def __init__(self, filename, mode = 'rb'):
    		assert mode in ('r', 'rb')
    		if not pack.Exist(filename):
    			raise IOError('No file or directory')
    		self.data = pack.Get(filename)
    		if mode == 'r':
    			self.data=_chr(10).join(self.data.split(_chr(13)+_chr(10)))
    
    	def __iter__(self):
    		return pack_file_iterator(self)
    
    	def read(self, len = None):
    		if not self.data:
    			return ''
    		if len:
    			tmp = self.data[:len]
    			self.data = self.data[len:]
    			return tmp
    		else:
    			tmp = self.data
    			self.data = ''
    			return tmp
    
    	def readline(self):
    		return self.read(self.data.find(_chr(10))+1)
    
    	def readlines(self):
    		return [x for x in self]
    
    __builtins__.pack_open = pack_open = pack_file
    
    _ModuleType = type(sys)
    
    old_import = __import__
    def _process_result(code, fqname):
    	# did get_code() return an actual module? (rather than a code object)
    	is_module = isinstance(code, _ModuleType)
    
    	# use the returned module, or create a new one to exec code into
    	if is_module:
    		module = code
    	else:
    		module = imp.new_module(fqname)
    
    	# insert additional values into the module (before executing the code)
    	#module.__dict__.update(values)
    
    	# the module is almost ready... make it visible
    	sys.modules[fqname] = module
    
    	# execute the code within the module's namespace
    	if not is_module:
    		exec(code, module.__dict__)
    
    	# fetch from sys.modules instead of returning module directly.
    	# also make module's __name__ agree with fqname, in case
    	# the "exec code in module.__dict__" played games on us.
    	module = sys.modules[fqname]
    	module.__name__ = fqname
    	return module
    
    module_do = lambda x:None
    
    def __pack_import(name,globals=None,locals=None,fromlist=None):
    	if name in sys.modules:
    		return sys.modules[name]
    
    	filename = name + '.py'
    
    	if pack.Exist(filename):
    		dbg.Trace('importing from pack %s\\n' % name)
    
    		newmodule = _process_result(compile(pack_file(filename,'r').read(),filename,'exec'),name)		
    
    		module_do(newmodule)
    		return newmodule
    		#return imp.load_module(name, pack_file(filename,'r'),filename,('.py','r',imp.PY_SOURCE))
    	else:
    		dbg.Trace('importing from lib %s\\n' % name)
    		return old_import(name,globals,locals,fromlist)
    
    def splitext(p):
    	root, ext = '', ''
    	for c in p:
    		if c in ['/']:
    			root, ext = root + ext + c, ''
    		elif c == '.':
    			if ext:
    				root, ext = root + ext, c
    			else:
    				ext = c
    		elif ext:
    			ext = ext + c
    		else:
    			root = root + c
    	return root, ext
    
    class PythonExecutioner: 
    
    	def Run(kPESelf, sFileName, kDict): 
    		if kPESelf.__IsCompiledFile__(sFileName): 
    			kCode=kPESelf.__LoadCompiledFile__(sFileName) 
    		else: 
    			kCode=kPESelf.__LoadTextFile__(sFileName) 
    
    		exec(kCode, kDict) 
    
    	def __IsCompiledFile__(kPESelf, sFileName): 
    
    		sBase, sExt = splitext(sFileName) 
    		sExt=sExt.lower() 
    
    		if sExt==".pyc" or sExt==".pyo": 
    			return 1 
    		else: 
    			return 0 
    
    	def __LoadTextFile__(kPESelf, sFileName): 
    		sText=pack_open(sFileName,'r').read() 
    		return compile(sText, sFileName, "exec") 
    
    	def __LoadCompiledFile__(kPESelf, sFileName): 
    		kFile=pack_open(sFileName)
    
    		if kFile.read(4)!=imp.get_magic(): 
    			raise 
    
    		kFile.read(4) 
    
    		kData=kFile.read() 
    		return marshal.loads(kData) 
    
    def execfile(fileName, dict): 
    	kPE=PythonExecutioner() 
    	kPE.Run(fileName, dict) 
    
    def exec_add_module_do(mod):
    	global execfile
    	mod.__dict__['execfile'] = execfile
    
    import builtins
    builtins.__import__ = __pack_import
    module_do = exec_add_module_do
    
    
    def GetExceptionString(excTitle):
    	(excType, excMsg, excTraceBack)=sys.exc_info()
    	excText=""
    	excText+=_chr(10)
    
    	import traceback
    	traceLineList=traceback.extract_tb(excTraceBack)
    
    	for traceLine in traceLineList:
    		if traceLine[3]:
    			excText+="%s(line:%d) %s - %s" % (traceLine[0], traceLine[1], traceLine[2], traceLine[3])
    		else:
    			excText+="%s(line:%d) %s"  % (traceLine[0], traceLine[1], traceLine[2])
    
    		excText+=_chr(10)
    	
    	excText+=_chr(10)
    	excText+="%s - %s:%s" % (excTitle, excType, excMsg)		
    	excText+=_chr(10)
    
    	return excText
    
    def ShowException(excTitle):
    	excText=GetExceptionString(excTitle)
    	dbg.TraceError(excText)
    	app.Abort()
    
    	return 0
    
    def RunMainScript(name):
    	try:		
    		exec(compile(open(name, "rb").read(), name, 'exec'), __main__.__dict__)
    	except RuntimeError as msg:
    		msg = str(msg)
    
    		import locale
    		if locale.error:
    			msg = locale.error.get(msg, msg)
    
    		dbg.LogBox(msg)
    		app.Abort()
    
    	except:	
    		msg = GetExceptionString("Run")
    		dbg.LogBox(msg)
    		app.Abort()
    	
    import debugInfo
    debugInfo.SetDebugMode(__DEBUG__)
    
    loginMark = "-cs"
    
    app.__COMMAND_LINE__ = __COMMAND_LINE__
    RunMainScript("prototype.py")
    

     

     

×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.