-
Notifications
You must be signed in to change notification settings - Fork 0
Procedure
Procedure는 v4 이하에서의 Item Conversion을 일반화한 개념으로, 서버에 스크립트를 등록하여, 필요한 경우 호출할 수 있다. v5 이상에서는 Javascript로 Procedure를 정의해 조건이나 반복, 산술 연산, 임시 변수, 시스템 제공 함수, 사용자 정의 함수 등을 사용할 수 있다.
##Procedure의 정의 Javascript의 function 정의 형식을 따른다. 전달하는 parameter는 Object type으로 1개를 받을 수 있다. 이 파라미터는 REST API를 호출할 때 query string으로 전달되며 복수의 key-value 쌍이 된다. procedure body 내에서는 Javascript를 이용할 수 있으며, Javascript 1.7 문법을 지원한다. 단, 일부의 제한사항이 있으며, 자세한 내용은 제한에서 다룬다.
리턴으로 지정한 변수는 REST 호출의 결과 Response에서 확인할 수 있다(call_return의 value). 리턴이 가능한 타입은 String, Number, Boolean, null, Object, Array이며 Object는 nesting이 가능하다.
- Procedure 정의 Example:
function levelup_item(params) {
// 아이템 강화 : sowrd + ring -> sword의 레벨증가
var sword = HObject.load("weapon_sword", params.sword_id);
if (sword.level<sword.max_level) {
// ring 아이템은 삭제하고,
HObject.destroy("ring", params.ring_id);
// sword는 레벨 증가
sword.level++;
HObject.save(sword); // sword의 속성이 변화됐으므로, 명시적으로 save를 해야 한다.
return sword;
}
}- REST API 호출 결과의 예
{
"result_code" : 0,
"call_return" : {
"class": "weapon_sword",
"id" : 342390329,
"level" : 3
}
}정의한 Procedure는 다음과 같은 방법으로 호출될 수 있다.
- REST API를 사용하여 호출한다. REST API의 Procedure Call를 참조한다.
- 즉시 수행으로 지정된 Mission의 수행완료 API를 호출하면, 지정된 프로시저가 호출된다. 보통 이 프로시저에서는 미션의 완료조건을 검사하고, 보상을 수행하는 내용으로 구성된다. REST API의 Mission을 참조한다.
- 즉시 수행이 아닌 Mission의 수행완료 API를 호출하면, reward_id를 받게 되어 있는데, 이를 이용해 Reward 실행을 실행하면, 지정된 프로시저가 호출된다. 프로시저의 호출 시점만 차이가 있을 뿐 위의 경우와 유사한 내용의 프로시저가 된다. REST API의 Mission과 Reward를 을 참조한다.
- Google, Apple, Naver 결제 완료 API를 호출하면 이와 연결된 프로시져가 호출된다. 보통 이 프로시저에는 결제가 완료된 후 아이템을 생성하거나 증가시키는 등의 작업을 수행하게 된다. 결제 완료와 관련된 내용은 API 문서에서 네이버 결제완료, Google 결제완료, Apple 결제완료를 참조한다.
##제공되는 라이브러리 Procedure에서 사용할 수 있도록 제공되는 Library는 다음과 같다.
- HObject : Hive5 object의 생성과 삭제, 값을 읽어오거나 저장하는 함수들
- HDataTable : 콘솔에서 정의한 Data Table을 Procedure에서 사용할 수 있도록 하는 함수들
- HSecurity : 데이터 보안을 위한 암호화, 메세지 다이제스트(message digest) 관련 함수들
- HLeaderboard : 리더보드와 관련된 함수들
- HMail : Mail과 관련된 함수들
- HUserLib : User Library와 관련된 함수들
###1. HObject
Hive5 object의 생성과 삭제, 값을 읽어오거나 저장하는 함수들이다. Hive5 object는 Hive5 시스템에서 사용하는 데이터 구조로, C에서의 구조체나 C++, Java등에서의 클래스와 유사하다(단, 객체지향에서의 클래스가 데이터와 메소드를 지칭하지만, Hive5 object는 메소드가 지원되지 않는 데이터의 집합이라고 볼 수 있다). Hive5 object에는 javascript의 Object로 표현되며, 동적으로 필드를 추가할 수 있고 그 내용을 바꿀 수 있어서 게임과 관련된 각종 정보들을 서버에 저장하고, 각종 판정 등에 이를 사용할 수 있다.
Hive5 object는 class 이름으로 생성한다. object를 생성하면 생성된 인스턴의 id를 할당받게 되므로 클래스 이름과 id를 통해 값들을 불러오거나 업데이트하거나 소멸시킬 수 있다. 이후 Hive5 object를 object로 표현하기로 한다. Javascript의 Object와 혼동을 피하기 위해서 이는 명시적으로 Javascript Object로 지칭할 것이다.
object를 생성할 때 사용한다. className은 ClassDescriptor에서 정의된 name이며, 해당 class의 object가 생성되어 리턴된다. ClassDescriptor에 정의되지 않은 클래스 이름이라도 사용가능하다. 이 경우에는 ClassDescriptor의 각 항목이 default로 적용된다.
- Example:
var player = HObject.create("item_bomb");생성된 object를 소멸시킬 때 사용한다. 소멸시킬 object의 className과 id를 넘긴다. id를 null로 하거나 id를 생략하고 className만 있다면, 싱글톤(singleton)의 모든 필드를 삭제한다는 의미다. load()도 id를 생략할 수 있는데 이 역시 싱글톤 객체를 지정하는 의미다. 싱글톤을 제외하고 생성되지 않는 객체를 소멸시키려고 하면 에러가 발생한다(Error Code 참조).
- Example:
HObject.destroy("item_bomb", "12");생성된 object를 불러올 때 사용한다. 불러올 object의 className과 id를 넘기면 해당 object의 값들이 Jacascript의 Object 타입으로 리턴된다. 없는 객체라면 에러가 발생한다(Error Code 참조). 싱글톤을 불러오려면 id를 null로 넘기거나 생략한다. 싱글톤 객체는 따로 생성할 필요없이 클래스 이름만으로 load하면 된다. 싱글톤 객체는 플레이어의 점수나 골드를 저장하는 등 따로 복수의 인스턴스를 생성할 필요없이 클래스 이름만으로 접근할 수 있는 경우에 사용하면 편리하며, 이와 반대로 아이템을 획득하거나 소멸시키는 경우에는 복수의 인스턴스가 필요하므로, 싱글톤이 아닌 인스턴스 생성이 더 적합하다.
- Example:
var player = HObject.load("player", null); //싱글톤
var player = HObject.load("player"); //null을 생략해도 싱글톤을 의미
var bomb = HObject.load("item_bomb", ins_id); //create로 생성된 인스턴스불러온 object의 필드값들을 변경한 후, 변경 내용이 서버에 반영되도록 저장할 때 사용한다. load의 결과로 받은 객체를 넘기게 된다. 만약 이 객체의 className과 id필드를 변경하면, save 대상 객체가 바꾸어지므로 주의해야 한다. 이렇게 대상을 변경하였는데, 그 대상 객체가 없는 경우라면 에러가 발생한다.
특정 필드를 삭제하고 싶은 경우에는 그 필드에 null을 할당한다.
- Example:
player.coin = player.coin + 1;
HObject.save(player)
bomb.flag = null // flag 필드를 삭제하게 됨
HObject.save(bomb)// 아이템 구매
function buy_item(params) {
//params
//index : 구매하려는 아이템의 고유번호(character table에 정의)
// index를 갖는 아이템 인스턴스를 생성하여, 인벤토리에 저장한다.
var player = HObject.load("player");
var tbl = HDataTable.load("item", {index:parseInt(params.index)});
if (tbl.length!=1)
return "일치조건 없음";
var target = tbl[0];
if (player.coin<target.price)
return "코인부족";
var item = HObject.create("item");
item.index = target.index;
HObject.save(item);
player.item_inv.push({id:item.id, index:item.index});
player.coin -= target.price;
HObject.save(player);
return player;
}###2. HDataTable
Hive5 콘솔에서 게임과 관련한 규칙이나 속성들을 Data Table로 저장할 수 있다. 이 테이블을 Procedure에서 사용할 수 있도록 Javascript 객체로 변환하는 함수다.
콘솔에서 정의한 Data Table의 값들을 procedure에서 사용할 수 있도록 가져온다. tableName은 콘솔에서 정의한 Data Table의 이름이며, 이 테이블의 모든 값들이 Javascript의 Array로 변환하여 리턴된다. Array의 내용은 컬럼과 값들의 Object가 된다. tableName으로 지정된 Data Table이 등록되지 않았으면 에러가 발생한다(Error Code 참조).
condition은 특정 조건에 해당되는 row들만을 가져올 때 사용한다. condition은 Javascript Object로 Data table의 컬럼 이름이 key가 되고, 검색 대상의 값이 value가 된다. 복수의 조건도 가능한데 모든 조건을 만족시키는 값들이 결과가 된다. 조건에 부합하는 결과가 없다면 비어 있는 Array가 되므로, length가 0이 된다.
- Example: exp_level라는 Data Table이 아래와 같이 정의되었다고 가정한다.
| exp_from | exp_to | level |
|---|---|---|
| 100 | 199 | 2 |
| 200 | 399 | 3 |
| 400 | 599 | 4 |
| 600 | 999 | 5 |
아래와 같이 호출하면,
var tbl = HDataTable.load("exp_level");tbl에는 아래와 같은 Javascript 객체로 리턴받는다.
[
{exp_from=100, exp_to=199, level=2},
{exp_from=200, exp_to=399, level=3},
{exp_from=400, exp_to=599, level=4},
{exp_from=600, exp_to=999, level=5}
]조건을 추가해서 다음과 같이 호출할 수도 있다.
var tbl = HDataTable.load("exp_level", {exp_from:200});tbl에 들어가는 결과는 아래와 같다.
[
{exp_from=200, exp_to=399, level=3}
]//경험치가 증가하여 레벨을 증가시킬 때 테이블을 참조
function increase_level_with_exp(params)
// table 로딩
var tbl = HDataTable.load("exp_level");
var player = HObject.load("player"); // id가 없으면 싱글턴을 의미
// table에서 exp범위로 찾아서 level을 세팅
for (i=0; i<tbl.length; i++) {
if (player.exp>=tbl[i].exp_from && player.exp<=tbl[i].exp_to) {
player.level = tbl[i].level;
HObject.save(player);
break;
}
}
}###3. HSecurity
데이터 보안을 위한 암호화, 메세지 다이제스트(message digest) 관련 함수들
SHA-1(Secure Hash Algorithm 1) 알고리즘을 이용하여 str으로 넘긴 데이터를 변환한다.
클라이언트에서 procedure를 호출할 때 점수 등을 넘겨야 되는 경우가 있다. 이 때 점수가 평문(plaintext)이므로, 악의적으로 변조하여 보낼 경우 보안상 취약하게 되므로, sha1등의 해쉬 알고리즘을 이용하여 일련의 검정을 추가하면 보다 안전하게 전송할 수 있다.
*Examples:
//클라이언트가 프로시져를 호출할 때, score와 player의 더한 값에 대해 sha1을 수행한 check를 같이 넘긴다고 가정한다
var player = HObject.load("player"); // player 정보를 로드하고,
// 동일한 방법으로 해쉬값을 만들어 비교한다
if (params.check != HSecurity.sha1(params.score+player.exp) {
return "invalid submit";
}SHA-256 알고리즘을 이용하여 str으로 넘긴 데이터를 변환한다.
MD5(Message-Digest algorithm 5) 알고리즘을 이용하여 str으로 넘긴 데이터를 변환한다.
###4. HLeaderboard
리더보드와 관련된 함수들
리더보드에 스코어를 제출할 때 사용한다. leaderboardId는 관리콘솔에서 생성한 리더보드의 id이며, score는 득점한 점수값이다. 리더보드 id가 유효하지 않는 경우에는 에러가 발생한다(Error Code 참조)
- Example:
HLeaderboard.submitScore(1, params.score);###5. HMail
Mail과 관련된 함수들
메일을 생성한다. tag를 붙이고자 할때는 array 타입의 tag를 parameter로 넘긴다.
- Example:
HMail.create("test mail", ["tag1", "tag2"]);친구에게 메일을 보낼 때 사용한다.
- Example:
HMail.send("friend_platform_user_id_1234", "test mail", ["tag1", "tag2"]);###6. HUserLib
User Library와 관련된 함수들
콘솔에서 정의한 User Library를 사용할 수 있도록 로드한다. 유저라이브러리는 javascript 기반의 함수나 global로 사용할 상수 등을 포함할 수 있다.
- Example:
HUserLib.require("quest_lib");프로시저와 관련된 에러는 크게 Javascript 내에서 일어나는 Runtime 에러와 Hive5의 Library나 구조에서 발생되는 에러가 있다.
Javascript에서 exception이 발생되면 결과의 result_code가 3001이며, 내용은 result_message에 표시된다. 구문 오류나 null 객체에 대한 인덱스 접근 등이 이에 해당한다. Javascript에서 exception을 throw해도 3001 코드가 리턴되므로, 디버킹 용도로 사용할 수 있다. 다음은 throw를 사용하는 예다
if (player.coin < 0)
throw("coin is less than 0");만약 if내의 조건이 참이어서 throw가 실행된다면 response는 다음과 같을 것이다.
{
"result_code" : "3001",
"result_message" : "coin is less than 0"
}###2. 그 외의 에러 제공되는 라이브러리나, Hive5 REST API와 연관된 에러들은 Error Code에 정의되어 있다. ClassDescriptor에서 Event Handler로 지정한 프로시저가 없다면, load때 다음과 같은 결과를 얻을 것이다.
{
"result_code" : "3101",
"result_message" : "Procedure Not Found"
}API 문서의 error code 참고
##제한
- Hive5 object의 필드를 Array로 선언했으면, 문자열의 키를 사용할 수 없다.
var player = HObject.load("player");
player.items = new Array();
player.items["type"] = "weapons"; // array인 필드에 문자열 키를 사용할 수 없다.
HObject.save(player); // 에러 발생함- Hive5 object의 필드가 Javascript의 Object인 경우에는 숫자형 키가 사용가능하다. 단 이 경우 실제 Array는 아니므로, length는 0이다.
var player = HObject.load("player");
player.missions = new Object();
player.missions[0] = "level_mission"; // object인 필드에 숫자형 키를 사용할 수 있다.
player.missions[1] = "score_mission";
HObject.save(player);- 리턴 타입으로는 Number, String, Boolean, null, Array, Object가 가능하다. Object는 nesting이 가능하다. function을 리턴할 경우 에러가 발생한다. Number type인 경우에도 NaN이나 Infinity를 리턴할 경우 에러가 발생한다.
수행시간은 다음과 같은 제한이 있다.
- 수행시간: 1000 ms 까지 허용
- Path: /:version/procedures/call/:name
- Authentication Header: X-APP-KEY, X-AUTH-UUID, X-AUTH-TOKEN
- Method: POST
- Request Parameter:
Name Type Description name String procedure name
procedure에 전달할 parameter는 query string 형태로 정의한다.
http://[server_url]/:version/procedures/call/proc1?param1=aaa¶m2=bbb
이렇게 넘겨진 parameter는 프로시저 내에서는 Javascript Object 타입인 params의 key, value 형태로 전달된다. 위 호출의 경우에는 params가 다음과 같은 값을 가지게 된다.
{ param1:"aaa", param2:"bbb"}즉, params.param1 또는 params.param2의 형태로 사용한다.
- Response Body: JSON
| Name | Type | Description |
|---|---|---|
| result_code | Number | Error Code 참고 |
| result_message | Option[String] | 실패한 경우에 메시지 있을 수 있음 |
| call_return | Null/String/Number/JSON Object | procedure call의 결과. call을 정의하는 것에 따라서 이 값의 type도 변경되니 유의 |