[TIP] 플러그인 디컴파일 후 참고해야 할 사항

2021. 4. 2. 18:40·소스모드/TIP

일반적으로 플러그인을 디컴파일하게되면 온전한 상태로 컴파일이 되지않는다.

온전히 컴파일 하기위해서 참고할만한 자료를 적어놓겠다.

 

1. Return 타입 수정

Plugin_Continue = 0, /**< Continue with the original action */
Plugin_Changed = 1, /**< Inputs or outputs have been overridden with new values */
Plugin_Handled = 3, /**< Handle the action at the end (don't call it) */
Plugin_Stop = 4, /**< Immediately stop the hook chain and handle the original */

 

Plugin_Continue - Let the hook continue as normal.
Plugin_Handled - Stop the engine from processing the hook.
Plugin_Changed - Feed the modified parameters back into the engine.
Plugin_Stop - Stop repeating timers.

INVALID_HANDLE is just another way to express '0' in terms of a handle. It is what the name implies, the handle is invalid, and can't really be used for anything.

 

그러나 주의점이 있다.

해당 함수에서 return 0;이 붙어있는경우 위를 보면 플러그인 컨티뉴를 써야할거 같지만 아니다.

써야하는것은 함수의 타입에 따라 다르다.

해당 함수에 Action이 붙어있다면 리턴을 써주고

없다면 return 0; 자체를 지워주면 되겠다.

 

2. SDKHook 타입 수정

SDKHook도 변환해야 해줄것이 생긴다. 바로 SDK훅의 타입이다.

참고로 SDKHookType:2 는 SDKHook_OnTakeDamage 이다. 나머지는 모르겠다.

 

SDKHook(client, SDKHookType:5, OnPostThink);
SDKHook(client, SDKHookType:20, OnPostThinkPost);
SDKHook(client, SDKHookType:11, OnTraceAttack);
SDKHook(client, SDKHookType:32, OnWeaponEquipPost);
SDKHook(client, SDKHookType:2, OnTakeDamage);
SDKHook(client, SDKHookType:33, OnWeaponSwitchPost);
는 아래와 같다
SDKHook(client, SDKHook_PostThink, OnPostThink);
SDKHook(client, SDKHook_PostThinkPost, OnPostThinkPost);
SDKHook(client, SDKHook_TraceAttack, OnTraceAttack);
SDKHook(client, SDKHook_WeaponEquipPost, OnWeaponEquipPost);
SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage);
SDKHook(client, SDKHook_WeaponSwitchPost, OnWeaponSwitchPost);

 

[변환 전]

SDKUnhook(client, SDKHookType:2, OnTakeDamageHook);

[변환 후]

SDKUnhook(clinet, SDKHook_OnTakeDamage, OnTakeDamageHook);

 

3. HookEvent 수정

HookEvent("round_start", EventStart, EventHookMode:1);
HookEvent("round_end", EventEnd, EventHookMode:1);

이런식으로 나오는데 훅 이벤트의 발동 순서 설정에는 

발동전, 발동즉시, 발동후 이렇게 나뉜다

그러나 구글링 해본결과 EventHookMode의 값이 뭐가 뭔지 찾아도 없다.

그리고 발동 순서도 차이가 크게 안난다. 전, 즉시, 후 이므로 그냥 지워버린다.

이런식으로 

HookEvent("round_start", EventStart);
HookEvent("round_end", EventEnd);

+ 최근에 구글링으로 다시 찾아봤다.

EventHookMode:1 = EventHookMode_Post

EventHookMode:2 = EventHookMode_PostNoCopy

라는데 실제 디컴파일 직접 해본결과(확정)

EventHookMode:1는 그냥 없애도 된다.

 

4. 타이머 수정

타이머의 시간과 실행함수는 그대로인 반면 3번째 인자값부터는 값이 바뀌므로 바꿔줘야한다.

세번째 인자 : 대상

네번째 인자 : 타이머의 속성

 

[대상의 경우]

- any:0은 대상이 없다는것을 뜻하므로 _로 치환해야한다.

[속성의 경우]

- 3 은 추정상 TIMER_FLAG_NO_MAPCHANGE인것같다

Ex ) CreateTimer(5.0, settimer, any:0, 3);
> CreateTimer(5.0, settimer, _, TIMER_FLAG_NO_MAPCHANGE);

 

5. 의미없는 변수

디컴파일을 하게되면 new var1, new var 2, ... new var 999

머 이런식으로 new var이 생기는데 해당 변수가 쓰이는 부분이 있으면 사용하면되고

사용하는 부분이 없다면 과감히 지워주면 되겠다.

아래 코드를 통해 실제 디컴파일 코드를 변환하는 과정을 보여주겠다.

 

[디컴파일 함수]

public OnGameFrame()
{
	new i = 1;
	while (i < MaxClients)
	{
		if (IsClientConnectedIngameAlive(i))
		{
			new entity = GetClientAimTarget(i, false);
			new var1;
			if (IsValidEntity(entity) && IsValidEdict(entity))
			{
				new String:classname[32];
				GetEdictClassname(entity, classname, 32);
				new var2;
				if (StrContains(classname, "prop_physics", false) != -1 && check[entity])
				{
					PrintCenterText(i, "바리게이트 체력 - %d HP 남음", health[entity]);
				}
			}
		}
		i++;
	}
	return 0;
}

[직접 변환 후]

public OnGameFrame()
{
	for(new i = 1; i <= MaxClients; i++)
	{
		if (IsClientConnectedIngameAlive(i))
		{
			new entity = GetClientAimTarget(i, false);
			if (IsValidEntity(entity) && IsValidEdict(entity))
			{
				new String:classname[32];
				GetEdictClassname(entity, classname, 32);
				if (StrContains(classname, "prop_physics", false) != -1 && check[entity])
				{
					PrintCenterText(i, "바리게이트 체력 - %d HP 남음", health[entity]);
				}
			}
		}
	}
}

 

해당 함수는 Action이 들어있지 않기 때문에 return 0; 은 과감히 지워버렸으며

디컴파일 특성상 생기는 의미없는 변수는 전부 지웠다.

그리고 while을 for로 고쳤다.

 

5. 조건문

if 후 else if를 쓴 부분은 아래와 같이 표시된다.

	if (500 < health[client] < 750)
	{
		SetEntityRenderColor(client, 255, 200, 200, 255);
	}
	else
	{
		if (350 < health[client] < 500)
		{
			SetEntityRenderColor(client, 255, 150, 150, 255);
		}
		if (100 < health[client] < 350)
		{
			SetEntityRenderColor(client, 255, 100, 100, 255);
		}
		if (0 < health[client] < 100)
		{
			SetEntityRenderColor(client, 255, 10, 10, 255);
		}
	}

물론 실제 우리는 else if를 이런식으로 쓰지 않는다 아래와 같이 고쳐주자.

	if (500 < health[client] < 750)
	{
		SetEntityRenderColor(client, 255, 200, 200, 255);
	}
	else if (350 < health[client] < 500)
	{
		SetEntityRenderColor(client, 255, 150, 150, 255);
	}
	else if (100 < health[client] < 350)
	{
		SetEntityRenderColor(client, 255, 100, 100, 255);
	}
	else if (0 < health[client] < 100)
	{
		SetEntityRenderColor(client, 255, 10, 10, 255);
	}

 

6. 엔티티

순수한 의미의 엔티티가 뿐만아니라 엔티티 설정 관련 부분도 바꿔주어야한다.

 

6-1. SetEntData

SetEntData(activator, g_offsCollisionGroup, any:2, 4, true);
SetEntData(Client, g_offsCollisionGroup, any:5, 4, true);

세번째 인자값을 보자. any:숫자의 형태를 하고있다. 실제 코드에선 저렇게 작성하지 않는다.

any:만 제거하면 될것같다.

요로코롬 ↓

SetEntData(activator, g_offsCollisionGroup, 2, 4, true);
SetEntData(Client, g_offsCollisionGroup, 5, 4, true);

 

7. 메뉴

7-1. CreateMenu

CreateMenu(WeaponmodMenuHandler, MenuAction:28);
CreateMenu(WeaponmodMenuHandler);

 

7-2. AddMenuItem

AddMenuItem(WeaponmodMenu, "galil", "galil", 0);
AddMenuItem(WeaponmodMenu, "galil", "galil");

8. Enum

만약 Enum값이 실수값이라면 포기하는게 좋다. 그 이유는 아래를 보면 알것이다.

[원본]

enum WeaponAttributes
{
	Float:RecoilType1,
	Float:RecoilType2,
	Float:FireRate,
	AutoMode,
	Float:GenericDamage,
	Float:HeadDamage,
	Float:TorsoDamage,
	Float:LimbDamage,
	Float:RagdollForce,
	BurstMode,
	InfiniteAmmo,
	QuickSwitch,
	Float:ModeFireRate,
	Float:StandSpread,
	Float:MoveSpread,
	Float:CrouchSpread,
	Float:MiscSpread
};

	new GalilInfo[WeaponAttributes];
	GalilInfo[RecoilType1] = 1.0;
	GalilInfo[RecoilType2] = -5.0;
	GalilInfo[FireRate] = -1.0;
	GalilInfo[AutoMode] = -5;
	GalilInfo[GenericDamage] = -5.0;
	GalilInfo[HeadDamage] = 1.0;
	GalilInfo[TorsoDamage] = 1.0;
	GalilInfo[LimbDamage] = 1.0;
	GalilInfo[RagdollForce] = 5.0;
	GalilInfo[BurstMode] = -5;
	GalilInfo[InfiniteAmmo] = 0;
	GalilInfo[QuickSwitch] = 0;
	GalilInfo[ModeFireRate] = -5.0;
	GalilInfo[StandSpread] = -1.0;
	GalilInfo[MoveSpread] = -1.0;
	GalilInfo[CrouchSpread] = -1.0;
	GalilInfo[MiscSpread] = -1.0;
	SetTrieArray(WeaponTypeTrie, "galil", GalilInfo[0], 17);

[디컴파일]

new GalilInfo[17];
GalilInfo[0] = 1065353216;
GalilInfo[1] = -1063256064;
GalilInfo[2] = -1082130432;
GalilInfo[3] = -5;
GalilInfo[4] = -1063256064;
GalilInfo[5] = 1065353216;
GalilInfo[6] = 1065353216;
GalilInfo[7] = 1065353216;
GalilInfo[8] = 1084227584;
GalilInfo[9] = -5;
GalilInfo[10] = 0;
GalilInfo[11] = 0;
GalilInfo[12] = -1063256064;
GalilInfo[13] = -1082130432;
GalilInfo[14] = -1082130432;
GalilInfo[15] = -1082130432;
GalilInfo[16] = -1082130432;
SetTrieArray(WeaponTypeTrie, "galil", GalilInfo, 17, true);

그렇다 가망이없다. 변수선언인 Enum자체를 찾아볼수없게되며,

정수값 소수값 의미가 없어질정도로 변형되어 원래값은 찾아볼수없게된다.

그리고 Enum 변수들은 직접적인 형태로 변형되어 원형으로의 복구는 불가능하다.

 

9. 프롭 타입(PropType)

new Float:minbounds[3] = 0.0;
	GetEntPropVector(0, PropType:1, "m_WorldMins", minbounds, 0);
	new Float:maxbounds[3] = 0.0;
	GetEntPropVector(0, PropType:1, "m_WorldMaxs", maxbounds, 0);
	SetEntPropVector(bombzone, PropType:0, "m_vecMins", minbounds, 0);
	SetEntPropVector(bombzone, PropType:0, "m_vecMaxs", maxbounds, 0);
	SetEntProp(bombzone, PropType:0, "m_nSolidType", any:2, 4, 0);

이런식으로 PropType:0이나 PropType:1이 뜨는데

0이 PropSend이고, 1이 PropData이다.

그러나 모든 오프셋을 일일이 알긴 힘든법.

아래와 같이 프롭타입을 자동인식해주는 코드를 이용하자.

 

decl String:buffer[64];
new PropType:proptype = PropType:-1;
	GetCmdArg(1, buffer, sizeof(buffer));
	if (!strcmp(buffer, "send"))
		proptype = Prop_Send;
	else if (!strcmp(buffer, "data"))
		proptype = Prop_Data;

 

아니면 https://forums.alliedmods.net/showthread.php?t=117723 참조

 

10. 메뉴 수정(Menu)

 

MenuAction:16 = MenuAction_End

DisplayMenu(메뉴핸들, 대상, 0); = 여기서 0은 MENU_TIME_FOREVER이다. 이외 숫자는 지속시간을 따로설정한것.

CreateMenu(menuhandler, MenuAction:28); 여기서 MenuAction:28은 없애버리자.

AddMenuItem(hMenu, "", szReadData, 1); 맨마지막 1은 ITEMDRAW_DISABLED 이다.

'소스모드 > TIP' 카테고리의 다른 글

[TIP] 신문법 훅 이벤트 변경점  (0) 2023.03.16
[TIP] 소스모드 개발시 참고하면 좋은 사이트  (0) 2021.12.17
[TIP] 소스모드 문법 혼용으로 인한 발생워링 고치는법  (0) 2021.04.01
[TIP] NPC의 관계 설정  (0) 2021.03.25
[TIP] 소스모드 디컴파일 사이트  (0) 2021.03.19
'소스모드/TIP' 카테고리의 다른 글
  • [TIP] 신문법 훅 이벤트 변경점
  • [TIP] 소스모드 개발시 참고하면 좋은 사이트
  • [TIP] 소스모드 문법 혼용으로 인한 발생워링 고치는법
  • [TIP] NPC의 관계 설정
백고미
백고미
  • 백고미
    백고미의 정신세계
    백고미
  • 전체
    오늘
    어제
    • 분류 전체보기 (125)
      • [ 공지사항 ] (0)
      • 정보 (14)
        • 워프레임 (5)
        • 게임 (3)
        • 군대 (1)
        • 이민 (1)
      • Java Spring (43)
        • JSP와 스프링 (34)
        • Tip (9)
      • Spring boot (1)
        • Tip (1)
      • 직업 정보 (2)
        • 경찰 공무원 (2)
        • AAFES (0)
        • HD GFD (0)
      • 리뷰 (1)
        • 인터넷 (1)
      • Life (2)
        • 운동 (1)
        • 자격증 (1)
      • 소스모드 (27)
        • CSGO (7)
        • CSS (0)
        • HL2DM (2)
        • L4D2 (1)
        • BMS (0)
        • TIP (16)
        • Extension (1)
        • 문법 (0)
      • C# (4)
        • s&box (4)
      • LUA (8)
        • Garry's Mod (8)
      • Resource (11)
        • Player Model (1)
        • Npc Model (1)
        • Weapon Model (2)
        • PropPhyics (6)
        • PropDynamic (1)
        • Texture (0)
        • Animation Texture (0)
        • Overlay (0)
        • Effect Sound (0)
        • Particle (0)
      • 일기장 (1)
        • TRH (4)
        • 스케줄 (1)
        • Els (0)
        • 프로젝트 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

    • John John한 블로그
  • 공지사항

  • 인기 글

  • 태그

    경기북부병무청 가는법
    병무청 가는 법
    경찰 간부후보생
    경찰공무원 가산점표
    경찰 공무원 응시 자격
    경기북부병무지청
    경기북부병무청
    경기북부 병무청 가는길
    경찰시험 응시 자격
    공찰공무원 필수과목
    병무청가는법
    운전면허 종류
    발표 PPT
    스쿼트 운동 효과
    윈도우10 참가자 프로그램
    경기북부 병무청
    경찰 가산점표
    병무청가는길
    경기북부병무청 망월사
    윈도우10 고양이
    키벨류
    경기북부 병무청 가는 법
    윈도우10 1주년
    윈도우10 닌자캣
    경기북부병무청 회룡역
    원동기장치면허
    경찰공무원 선택과목
    경기북부 병무청 가는 길
    병무청 가는 길
    순경 가산점
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
백고미
[TIP] 플러그인 디컴파일 후 참고해야 할 사항
상단으로

티스토리툴바