Skip to content
isdnetworks
Go back

빌드할 때마다 번호가 바뀌었다

Cocos2d-x 클라이언트에서 아이템 번호를 enum 순서로 매기고 있었다. 새 아이템을 추가했더니 기존 UserDefault.xml 의 아이템이 다른 것으로 바뀌었다.

Table of contents

Open Table of contents

순서대로 매기고 있었다

enum 에 순서대로 적어 두고 그 숫자를 setIntegerForKey 로 넣고 있었다. 가운데에 하나를 넣으니 그 뒤가 전부 하나씩 밀렸다.

enum ItemType {
    ITEM_POTION,      // 0
    ITEM_ELIXIR,      // 1  ← 새로 넣음
    ITEM_SWORD,       // 2  ← 1에서 2로 바뀜
};

UserDefault.xml 에 1 이 들어 있던 사람은 이제 다른 아이템을 끼고 있다. .cpp 에서는 이름으로 쓰니 아무 문제가 없어 보인다. 저장된 쪽은 숫자만 들고 있다.

값을 고정했다

enum 에 숫자를 직접 적었다. 순서를 바꾸거나 가운데에 넣어도 값이 안 바뀐다.

enum ItemType {
    ITEM_POTION = 100,
    ITEM_SWORD  = 101,
    ITEM_ELIXIR = 104,     // 새 것은 뒤에 붙인다
};

100 부터 시작한 것은 getIntegerForKey 가 없는 키에 기본값 0 을 주기 때문이다. 0 이 실제 아이템이면 없는 것과 구분이 안 된다.

아이템 하나를 없앨 때도 그 번호를 주석으로 남겼다. 지워 버리면 다음 사람이 그 번호를 다시 쓸 수 있다. 그러면 옛 UserDefault.xml 이 엉뚱하게 읽힌다.

판 번호와 옮기는 표를 뒀다

구조가 바뀔 때를 대비해 save_version 키를 넣었다. 읽을 때 그 값을 보고 다르게 처리한다. 없으면 옛 것과 새 것을 구분할 방법이 없어서 처음부터 넣어 뒀어야 했다.

이미 Android 마켓에 나간 앱이 있어 옛 판을 옮기는 코드도 만들었다.

static const int oldToNew[] = { 100, 101, 102, 103 };
int old = d->getIntegerForKey("equipped", -1);
if (old >= 0 && old < 4) d->setIntegerForKey("equipped", oldToNew[old]);

옛 숫자와 새 숫자의 대응표는 지우면 안 된다. 옮기다 값이 이상하면 아무것도 안 낀 상태로 뒀다. 엉뚱한 것을 끼는 것보다 낫다. CCLOG 에는 무엇이 안 옮겨졌는지 남겼다.

서버와의 대응과 확인

서버도 같은 아이템을 다루는데 MySQL 쪽은 POTION 같은 문자열 코드를 쓰고 있었다. JSON 응답에도 그 문자열이 실려 온다. 옮기는 표가 또 필요했다. 한쪽만 고치면 어긋나므로 표를 한 파일에 두고 양쪽이 그것을 보게 했다.

옮기는 코드를 만들고 나서 실제 옛 판 저장 파일로 돌려 봤다.

$ adb shell run-as <패키> cat /data/data/<패키>/UserDefault.xml > old_save.xml

adb pull 로는 못 꺼낸다. 앱 전용 폴더라 권한이 없다. run-as 는 디버그로 서명된 빌드에서만 된다.

경로에 files/ 가 없는 것은 Cocos2d-x 의 getWriteablePath()/data/data/ 에 패키지 이름만 붙이기 때문이다.

옛 파일을 run-as 로 다시 밀어 넣고 앱을 켜서 아이템이 그대로인지 봤다. 새 파일로만 시험하면 옮기는 코드가 도는지조차 알 수 없다.

옮긴 뒤 다시 켰을 때 또 옮기지 않는지도 확인했다. save_version 을 안 올리면 켤 때마다 옮긴다. 두 번 옮기면 100 이 다시 대응표를 타서 엉뚱한 값이 된다.

정리


Share this post on:

Previous Post
애니메이션이 건너뛰었다
Next Post
주석이 옛날 동작을 설명하고 있었다