강좌/Minecraft Mod 제작2015. 12. 14. 01:06

강의 환경 : forge-1.7.10-10.13.0.1230-1.7.10

배경 지식 : 텍스처

선행 과정 : 커스텀 블록 제작, 블록 메타데이터

강의 목표 :

  1. 블록에 텍스처를 부여할 있다.

  2. 메타데이터 값을 불러오고 이용하는 방법을 안다.

주의: 이 강좌는 1.8+에서 완전히 변경된 부분에 대한 강좌입니다.

 

지금까지 여러분은 자신만의 블록을 만들어 볼 수 있었습니다!

 

하지만 슬프게도 분홍색과 검은색 체크무늬가 그려진 모습밖에 보실 수 없었겠지요.

 

그래서 이번 강좌에서는 블록에 텍스처를 부여하는 방법 강좌를 하고자 합니다.

 

1. 블록의 6면에 같은 텍스처 부여하기

이 부분은 커스텀 블록 제작 강좌에서 이미 다뤘던 내용입니다.

 

Block#setTextureName(String textureName)을 이용하시면 됩니다.

 

 

이때 textureName은 '(모드 ID):(텍스처 이름)' 의 형식이고,

 

실제 경로는 '프로젝트 경로/src/main/resources/assets/(모드 ID)/textures/blocks/(텍스처 이름).png' 에 해당하게 됩니다.

 

이제 6면이 같은 색으로 된 블록을 확인하실 수 있습니다.

 

 

2. 방향과 메타데이터에 따라 다른 블록 텍스처 적용하기

 

이번에는 방향과 메타데이터에 따라 다른 블록 텍스처를 적용하는 방법을 알아봅시다.

 

그러기 위해 텍스처(Icon, 아이콘)을 등록하고, 배정하는 단계를 거쳐야 합니다.

 

  • 아이콘 등록하기

    우선 사용하고자 하는 텍스처를 아이콘으로 등록하는 방법을 알아봅시다.

     

    먼저 Block#registerBlockIcons(IIconRegister register)를 오버라이딩해야 합니다.

     

    이 메소드는 마인크래프트에 블록의 텍스처가 로딩될 때 자동으로 호출되며, 이 메소드가 갖는 인자 'IIconRegister register'를 통해 아이콘을 특정 경로로부터 가져올 수 있습니다.

     

    예를 들어, 다음과 같은 위치에 이미지가 있다고 합시다.

    '프로젝트 경로/src/main/resources/assets/(모드 ID)/textures/blocks/(텍스처 이름).png'

     

    이때 IIconRegister#registerIcon("(모드 ID):(텍스처 이름)")를 이용하여 이 이미지에 해당하는 아이콘(IIcon)을 가져올 수 있습니다.

     

    이렇게 가져온 아이콘을 저장해 주시면 됩니다.

     

    단, IIcon과 registerBlockIcons는 클라이언트(minecraft.exe)에만 존재하기 때문에, 관련 멤버변수나 메소드 선언시 @SideOnly(Side.CLIENT)를 반드시 윗줄에 써 주어야 합니다!

     

    다음은 예제입니다.

     

    텍스쳐 경로:

     

    코드:

     

  • 아이콘 배정하기

    이제 각 면에 메타데이터에 따라 다른 아이콘을 배정해 보아야겠죠?

     

    그러기 위해서는 Block#getIcon(int side, int meta)를 이용하시면 됩니다!

     

    이때 meta는 메타데이터이고, side는 다음과 같습니다.

    0 : DOWN, 아래 방향

    1 : UP, 위 방향

    2 : NORTH, 북쪽 방향

    3 : SOUTH, 남쪽 방향

    4 : WEST, 서쪽 방향

    5: EAST, 동쪽 방향

    각 경우에 맞도록 아이콘을 리턴해 주시면 됩니다. 단, 이 메소드 역시 @SideOnly(Side.CLIENT)가 필요합니다.

     

    예제로 돌아가서, 방향을 갖는 메타데이터 블록에 텍스처를 배정해 봅시다.

     

    앞면에는 tutorialfront, 윗면/아랫면에는 tutorialtop, 나머지에는 tutorial을 부여해서 방향을 구별하도록 합시다.

     

    위/아랫면의 경우 side는 0과 1이 되겠죠?

     

    그리고 앞면의 경우에는 향하는 방향을 메타데이터로 했으니, side와 일치하는 방향인지를 보면 됩니다.

    (이때 메타데이터는 4방향, side는 6방향을 표시하므로 값은 다릅니다. 다행히도 directionToFacing이라는 배열로 변환이 가능합니다.)

     

    결과적으로 다음과 같이 구현됩니다.

     

    다음과 같이 잘 된다는 것을 알 수 있습니다.

     

     

    • 포지forge-1.7.10-10.13.0.12xx-1.7.10 버전 이상에서는 수정해야 할 사항이 하나 있습니다.

      TileEntity가 아닌 모든 블록에 대해 onBlockAdded가 onBlockPlaced 호출 전후에 1번씩 호출되므로,

      메타데이터가 0인 경우에만 onBlockAdded에서 메타데이터를 설정하도록 해 주어야 합니다. 다음과 같이.

       

 

3. 위치에 따라 블록의 텍스처 적용하기

이제 위치에 따라 다른 블록 텍스처를 적용하는 방법을 알아봅시다. (멀티블록 구조와 타일엔티티에 필요합니다.)

 

우선 2번의 아이콘 등록 단계는 똑같이 해 주시고, 배정 단계만 달리해 주시면 됩니다.

 

여기서는 meta와 side를 이용한 버전 대신 Block#getIcon(IBlockAccess world, int x, int y, int z, int side)를 이용해서 배정하면 됩니다.

 

world은 블록이 속한 월드이고, x, y, z는 좌표이며, side는 아까 알아봤던 방향입니다.

 

이렇게 작은 차이만 있으니 예제는 제공하지 않습니다. 한번 직접 해 보세요!

 

(+ 관련 예제를 타일엔티티 편에서 다룰 예정입니다)

 

Posted by Abastro

댓글을 달아 주세요

  1. ㅁㄻ

    이제 강좌는 더 이상 쓰지 않는 건가요?

    2016.03.26 17:37 [ ADDR : EDIT/ DEL : REPLY ]

강좌/Minecraft Mod 제작2015. 11. 11. 23:00

강의 환경 : forge-1.7.10-10.13.0.1160-1.7.10

배경 지식 : 데이터 

선행 과정 : 커스텀 블록 제작

강의 목표 :

  1. 블록의 메타데이터를 이해할 있다.

  2. 메타데이터 값을 불러오고 이용하는 방법을 안다.

주의: 이 강좌는 1.8+에서 완전히 변경된 부분에 대한 강좌입니다.

 

이번 강좌에서는 블록의 메타데이터에 대해 알아보도록 하겠습니다.

 

1. 메타데이터란?

 

메타데이터란, 월드의 특정 위치에 있는 블록에 지정된 추가적인 데이터입니다.

 

 

이를테면, 위 사진에서 화로에도 메타데이터가 추가로 저장됩니다.

 

뿐만 아니라, 그 아래에 있는 흙 블록에도, 심지어 공기 블록까지 모두 메타데이터를 저장하고 있습니다.

 

한 마디로 말하자면, 월드에 존재하는 모든 블록에 블록 타입(ID)과 함께 저장되는 것이 메타데이터입니다!

 

이 메타데이터는 다양한 목적에 쓰이는데, 그 예로 다음과 같은 것들이 있습니다:

 

1. 블록이 놓인 방향 (화로의 경우 4가지, 디스펜서의 경우 6가지 방향이 있습니다)

2. 물 수위 (가마솥) 혹은 레드스톤 밝기, 작물의 성장 정도

3. 침대에서의 위치, 문의 열림 여부

4. 색 등의 종류 (양털, 스테인드글라스, 묘목 등)

 

이러한 메타데이터는 4비트의 데이터로서, 0~15까지 16가지의 데이터밖에 표현할 수 없습니다(…)

 

하지만 간편하게 쓸 수 있는 만큼 상당히 많이 사용됩니다.

 

이제부터 이 메타데이터를 사용하는 방법을 알아보도록 하겠습니다!

 

 

2. 메타데이터 이용 방법

 

메타데이터는 보통 평범한 int 값으로 주어집니다. 0~15 사이의 값이죠.

 

이 값을 가져오고, 저장하며, 적절히 이용할 줄 알면 됩니다.

 

1. 메타데이터 가져오기(구하기)

 

일반적인 경우 사용하고자 하는 메소드에 메타데이터가 주어지는 경우가 많습니다.

 

그렇지 않은 경우에도, 해당 블록의 위치(x,y,z좌표)와

 

월드 인스턴스에 해당하는 World 혹은 IBlockAccess객체를 갖고 있다면,

 

World#getBlockMetadata(int x, int y, int z) 혹은 IBlockAccess의 동일한 메소드를 사용하면 됩니다.

 

(+ 블록도 getBlock(int x, int y, int z)로 가져올 수 있습니다)

 

2. 메타데이터 저장하기

 

반대로 메타데이터를 지정하고 싶다면 어떻게 해야 할까요?

 

다음 2가지 메소드를 이용하시면 됩니다.

 

World#setBlock(int x, int y, int z, Block block, int metadata, int flag)

이 메소드는 x, y, z 좌표에 있는 블록을 바꾸되,

 

블록 타입이 block, 메타데이터가 metadata가 되도록 지정합니다.

 

이때 flag는

- 1은 블록 업데이트 메소드를 호출합니다.

- 2는 패킷을 클라이언트로 보냅니다.

- 4는 블록이 렌더링되는 것을 막습니다.

이들을 더한 플래그를 사용하면 더해진 작업들이 모두 수행됩니다.

즉 3을 선택하면 업데이트 메소드를 호출하고 패킷을 보내며,

7을 선택하면 모든 작업이 실행됩니다.

 

한편 메타데이터만 바꾸는 방법도 있는데요,

 

World#setBlockMetadataWithNotify(int x, int y, int z, int metadata, int flag)

 

이 메소드를 이용하면 메타데이터만 바꿀 수 있습니다.

 

3. 메타데이터에 여러 데이터 담기

 

만약 울타리 문처럼 종류와 방향을 함께 저장하고 싶다면 어떻게 해야 할까요?

 

이 경우 방향은 2가지, 종류는 4가지라 해 봅시다.

 

그러면 2*4=8이므로 공간은 충분함을 알 수 있습니다.

 

그럼 다음과 같이 하면 됩니다:

 

메타데이터를 meta라 합시다.

이때 meta%4 를 종류, meta / 4를 방향이라 하면,

종류는 0,1,2,3 중의 하나의 값, 방향은 0,1중의 하나의 값이 됩니다.

각각의 수들에 의미를 부여하면 되겠죠.

반대로 종류를 sp, 방향을 dir이라 하면,

메타데이터는 간단히 sp + dir * 4가 됩니다.

 

비트 연산을 잘 아신다면,

4가 거듭제곱수이므로 <<2, &3과 같은 연산자를 활용하셔도 됩니다.

 

 

3. 메타데이터의 기본적인 응용

 

이제 메타데이터를 응용하여 몇 가지 작업을 해 봅시다!

 

1. 블록 설치 시 메타데이터 지정하기

 

주로 메타데이터는 블록의 방향과 같은 데이터를 저장하는 데 쓰입니다.

 

따라서 블록이 설치될 때 이런 데이터를 결정해 주어야겠죠.

 

커스텀 블록 제작 강좌까지의 과정을 거친 블록에 이를 적용해 보도록 하겠습니다.

 

 

위와 같이 onBlockAdded, onBlockPlacedBy 2개의 메소드를 필요로 합니다.

 

이들은 블록이 설치될 때 호출되는 메소드인데,

 

일반적으로 onBlockAdded는 항상 호출되며, 엔티티가 설치한 경우 onBlockPlacedBy가 그 뒤에 호출됩니다.

 

onBlockAdded에서는 열린 부분을 향하도록,

 

onBlockPlacedBy에서는 블록을 설치한 엔티티를 향하도록 해 봅시다.

 

이때 Direction 클래스를 이용하면 방향을 좀 더 쉽게 구현할 수 있습니다.

(0: 남쪽, 1: 서쪽, 2: 북쪽, 3: 동쪽 이 됩니다.)

 

우선 onBlockAdded 메소드에서는 각각의 방향에 대해서 체크하되,

 

위의 코드는 바라보고 있는 방향의 facing블록은 투명하고, 반대의 블록은 불투명할 때

 

그 방향으로 블록을 설치하도록 해줍시다.

 

(*서버인지를 체크하기 위해 '!world.isRemote'를 이용합니다)

 

 

그럼 위와 같이 됩니다.

 

여기서 Block#func_149730_j()는 제 포지 버전에서 아직 해석되지 않은 메소드인데, 해석된 경우 Block#isOpaque()의 형태일 겁니다.

 

이를 통해 이쪽 방향의 블록이 불투명한 블록인지를 판단합니다.

 

그 다음 onBlockPlacedBy 메소드는 엔티티가 향하는 반대 방향을 향하도록 해주어야겠죠?

 

그러러면 우선, 엔티티가 위의 방위들 중에서 어느 방향을 향하는지 구해야 합니다.

 

엔티티가 향하는 방향은 rotationYaw가 결정하는데,

 

남쪽에서 0.0도의 값을 갖고 시계방향으로 돌아가며 360.0도까지 증가합니다.

 

여기에 360으로 나눈 다음 4를 곱하면 남, 서, 북, 동에서 각각 0, 1, 2, 3의 값을 갖게 됩니다.

 

반올림하기 위해 0.5를 더하고 정수부분만 추출하면 방위에 해당하는 값을 얻을 수 있습니다.

 

이제 반대편을 향하기 위해 2를 더해주면 됩니다.

 

 

코드로 작성하면 위와 같이 간단합니다(…)

 

2. Pending…

 

Posted by Abastro

댓글을 달아 주세요

  1. 비밀댓글입니다

    2016.04.02 21:23 [ ADDR : EDIT/ DEL : REPLY ]

강좌/Minecraft Mod 제작2015. 11. 9. 15:51

강의 환경 : forge-1.7.10-10.13.0.1160-1.7.10

강의 목표 :

1. 서버와 클라이언트의 개념을 이해할 있다.

2. 프록시를 이용하여 서버와 클라이언트 코드를 통일적으로 작성할 있다.

 

 

이 강좌에서는 예고했던 대로 프록시에 대해서 다뤄보도록 하겠습니다.

 

프록시를 간단히 설명하자면, 마인크래프트 서버 측과 클라이언트 측의 차이를 해결하기 위한 방법입니다.

 

헌데 모드에서의 서버와 클라이언트는 일반적으로 알고 있는 것과 다르므로 이 부분부터 짚고 넘어가도록 하겠습니다.

 

서버 (Server)

클라이언트(Client)

위치

- 마인크래프트 서버 (항상 활성)

- 마인크래프트 클라이언트

* 싱글플레이 중 활성

* LAN서버가 열려 있을 시에도 활성

마인크래프트 클라이언트

(항상 활성)

도식

역할

* 마인크래프트 월드 전체를 담당

(전지적 시점에서 월드를 컨트롤)

 

* ex) 월드 생성 및 저장,

엔티티(몹) 스폰 및 관리,

블록 상태 관리,

인벤토리 관리,

폭발, 불 등의 기작 제어 등

 

(엔티티에는 플레이어도 포함됩니다.)

* 마인크래프트 월드를 1인칭 시점에서 플레이어에게 보여주는 역할

(클라이언트에도 (관상용) 월드는 존재)

 

*서버의 행동을 그대로 따라하며

결과를 보여줌

 

* 플레이어의 행동은 대부분 패킷을 통해 서버로 전달, 서버와 클라이언트 양측에서 처리

 

* ex) 엔티티/블럭/아이템을 보여줌,

플레이어 자신의 행동 제어(일부)

스레드(Thread)

Server Thread

(* 서버 프로그램에서 Server Thread만 존재)

Client Thread

주요 클래스

관리자: MinecraftServer

월드: WorldServer

관리자: Minecraft

월드: WorldClient

 

한편 서버도 서버 프로그램에서 작동되느냐, 클라이언트와 같이 작동되느냐에 따라 달라지는데요,

 

각각을 Integrated Server, Dedicated Server라 합니다.

 

이들은 다음과 같은 차이점을 가집니다.

 

차이점

Integrated Server

Dedicated Server

위치

Minecraft.exe에서 월드가 열려 있을 때 활성

(싱글플레이, LAN 서버)

MinecraftServer.jar 와 같은 서버 프로그램

(실행시 항상 활성)

클라이언트와의 관계

동시에 같이 존재 (Thread를 달리함)

같이 존재하지 않음

세이브 데이터 위치

프로파일 위치(보통 .minecraft)

서버 프로그램 위치

(추가 예정)

  

 

그러니까 싱글플레이, LAN 서버, 멀티플레이 각각에서 다음과 같이 존재합니다.

 

서버측

클라이언트측

싱글플레이(SSP)

Integrated Server

O

LAN서버

Integrated Server

(LAN으로 플레이어 입장 가능)

O

멀티플레이(SMP)

Dedicated Server

(Minecraftserver.exe)

(Minecraft.exe)

 

(참고로, 한 프로그램 내에서 돌아가는 서버와 클라이언트조차도 서로 통신을 합니다. 일관성을 유지하기 위해서죠)

 

 

다시 모드 제작으로 돌아가봅시다.

 

만약 마인크래프트가 싱글 혹은 LAN 플레이만 지원하거나, 아니면 멀티플레이만 지원했다면,

 

모드를 제작할 때에도 서버와 클라이언트, 즉 Server Side와 Client Side의 구분만 잘 해주면 되었을 것입니다.

 

문제는 마크가 둘 다 지원한다는 데에 있습니다. 그에 따라 모드 제작에서도 Integrated Server와 Dedicated Server 환경이 모두 존재하게 됩니다.

 

그래도 모장과 포지 제작팀은 저 둘을 할 수 있는 만큼 비슷하게 만드려는 시도를 합니다.

 

하지만 클라이언트가 같이 돌아가는 경우와 그렇지 않은 경우는 차이가 날 수밖에 없었습니다.

 

결국 결론은, 모드 제작에서도 이를 고려해주어야 한다는 겁니다. 그리고 이 부분에서 항상 많은 실수와 오류가 발생하죠.

 

그나마 다행인 점은 고려해주어야 하는 경우가 그리 많지는 않다는 것입니다.

 

 

포지 팀도 이런 애로사항을 잘 알고 있었고, 그러한 경우들을 통합적으로 관리하기 위한 도구를 하나 창조하였습니다.

 

그 도구가 바로 '프록시(Proxy)'입니다!

 

주의: 여기서의 Proxy는 넷상의 프록시 서버와는 다른 개념입니다!

 

프록시는, 일반 마인크래프트 프로그램(Minecraft.exe)과 마인크래프트 서버 프로그램(주로 Minecraft_Server.exe) 를 구분해서,

 

두 경우에 서로 다른 코드를 동작하도록 해주는 도구입니다. (정확히는 각 경우에 대해 작동하는 클래스를 바꾸어 줍니다.)

 

이러한 프록시는 주로 다음의 문제를 해결하기 위해 쓰입니다.

 

# Dedicated Server에서도 클라이언트용 소스가 남아있는 문제

 

일반적인 모드는 클라이언트와 서버 양측 모두를 제어합니다. 그런데 이 경우, Dedicated Server에서 치명적인 문제가 생길 수밖에 없습니다.

 

모드 파일은 하나이지 둘이 아니다보니, 이것으로 Dedicated Server와 Integrated Server 모두를 돌려야 한다는 데에서 문제가 생깁니다.

 

Integrated Server 환경에서는 서버와 클라이언트가 모두 필요하니, 모드 파일에서도 둘 모두를 지원해야 하는 반면,

 

Dedicated Server에서는 마인크래프트 서버만 있고 클라이언트가 없기 때문에 사용되지 않는 클라이언트 부분은 무용지물이 됩니다.

 

그 뿐만 아니라, 클라이언트용 마인크래프트 코드가 없기 때문에 심지어 크래시를 터뜨리게 되죠.

 

바로 여기서 프록시가 해결사로 등장합니다.

 

프록시는 일반 마인크래프트 프로그램과 마인크래프트 서버 프로그램을 구분해준다고 했었죠?

 

여기서 일반 마인크래프트 프로그램은 Integrated Server 환경이고, 마인크래프트 서버 프로그램은 Dedicated Server 환경인 것을 생각하면, 답이 나옵니다.

 

즉 프록시는 각각의 환경에 대해 실행되는 코드를 다르게 해주는 역할을 하는 것입니다.

 

더 자세하게는, 클라이언트에서만 실행되어야 하는 코드 (ex. 렌더링 관련)의 경우에 이 위치에 놓이게 됩니다.

 

이제 코드를 통해 직접 그 사용법을 알아보도록 합시다.

 

 

갑자기 많은 코드가 추가되었죠? 하나 하나 설명을 해 드리겠습니다.

 

@Instance

모드 (기반) 클래스의 인스턴스를 지정해 주는 어노테이션입니다. 이렇게 지정된 전역변수는 그 모드 클래스의 인스턴스로서 기능하게 되죠.

항상 이 인스턴스를 이용하여 모드 클래스에 접근하면 됩니다. 이렇게 하지 않고 인스턴스를

 

@Instance(value=MODID)

public static (모드 클래스) instance;

 

이런 식으로 선언하시면 됩니다. 저의 경우 모드 아이디가 "abrtutorial" 이므로 이 값을 넣었습니다. 이런 식으로 넣어도 되지만

AbrTutorial.MODID 이런 식으로 전역변수로 선언했던 모드 아이디를 대입해도 됩니다.

 

 

@SidedProxy

이 글에서 계속 이야기했던, 바로 그 프록시를 제시해 주는 어노테이션입니다. 다음과 같이 선언합니다.

 

@SidedProxy(clientSide="(클라이언트 프록시 클래스의 경로)", serverSide="(서버 프록시 클래스의 경로)")

public static (프록시 클래스) proxy;

 

여기서, '클래스의 경로'에 들어가는 것은 클래스가 위치한 패키지까지 모두 표시한 클래스의 이름을 나타내는 문자열입니다.

영어로는 Fully Qualified Name 이라고도 합니다.

 

또한, 클라이언트 프록시와 서버 프록시는 사이드 자체와는 관련이 없음을 주의하셔야 합니다.

클라이언트 프록시는 일반 마인크래프트용, 즉 Integrated Server에서 작동하는 프록시입니다.

반면 서버 프록시는 마인크래프트 서버용입니다. Dedicated Server에서 작동하는 프록시이죠.

 

어쨌든, 이렇게 프록시는 기본적으로 클래스로 구현됩니다.

그리고 환경에 따라 프록시 인스턴스에 다른 프록시 클래스가 적용되는 것이죠.

 

원칙적으로는 프록시의 기반 클래스로 BaseProxy를 두고, 클라 프록시를 ClientProxy, 서버 프록시를 ServerProxy로 두어야 하지만,

일반적으로는 서버 프록시를 따로 둘 필요가 없기 때문에 이를 CommonProxy로 두고,

클라 프록시를 ClientProxy로 두어 CommonProxy를 상속받게 됩니다.

 

그래서 저도 마찬가지로 abr.tutorial 패키지에 CommonProxy와 ClientProxy의 두 프록시 클래스를 만들고, 저렇게 사용한 것입니다.

 

정말 특별한 모드를 제작하시는 것이 아니라면, 저처럼 그대로 따라하셔도 거의 문제가 없습니다.

 

 

그러면 이제 정말로 프록시를 쓰는 법을 알려드리도록 하겠습니다. 직접 써 보면 더 이해가 잘되겠죠?

 

먼저 어떻게 써야 하는지를 생각해 봅시다.

프록시의 가장 중요한 용도는, 클라이언트에서는 꼭 필요하지만 서버에서는 작동하지 않는 코드를 프록시에 위치시키는 것이라고 했었죠?

 

그 예를 살펴보자면, 우선적으로 렌더링이 있습니다.

 

렌더링이란, 프로그래밍에서의 '그리기' 에 해당하는 개념인데, 바로 우리가 보는 화면을 그려주는 것이죠.

 

우리도 우리가 만든 블럭이나 아이템, 몹 등을 직접 그려줘야 할 일이 있을지도 모릅니다.

 

그러기 위해서는 렌더링을 도맡아 해줄 '렌더러(Renderer)' 내지 '렌더링 핸들러(Rendering Handler)' 객체가 필요하게 되고,

이 객체들을 포지에 등록(Register) 해줄 필요도 생기죠.

 

문제는, 역시 이들이 클라이언트에서만 작동한다는 것입니다. 그러므로 등록(레지스터) 작업도 당연히 프록시에서 이루어져야 하죠.

 

그러면 이 부분을 개략적으로 프록시로 구현해보기로 합시다. 우선 프록시에 렌더러들을 등록할 메서드를 하나 새로 만들어보죠.

 

CommonProxy.java:

 

ClientProxy.java:

 

여기서 CommonProxy는 마크 서버용, ClientProxy는 일반 마크용이므로,

 

렌더러 등록(레지스터) 은 당연히 ClientProxy에서만 하게 될겁니다.

 

이제 다음과 같이 모드 클래스의 init 메서드로 하여금 이 메서드를 호출하게 하면 됩니다.

 

물론 이렇게 하면 단순히 init 메서드에서 등록해준 경우와 동일하겠지만, 서버에서 크래시를 내지는 않겠죠!

 

 

여기까지 사이드 개념과 Integrated/Dedicated 환경 개념을 알아보고, 프록시를 이용하는 법을 알아보았습니다.

 

다음 강좌에서는, 본격적으로 블럭을 만들어 보도록 하겠습니다!

Posted by Abastro

댓글을 달아 주세요