Skip to content
Artie Choi edited this page Oct 15, 2015 · 28 revisions

Script의 개념

콘솔을 통해 스크립트를 등록할 수 있고 클라이언트에서 이 스크립트를 실행할 수 있다. Javascript로 Script를 정의해 조건이나 반복, 산술 연산, 임시 변수, 시스템 제공 함수, 사용자 정의 함수 등을 사용할 수 있다.

Script의 정의

Javascript의 function 정의 형식을 따른다. 전달하는 parameter는 Object type으로 1개를 받을 수 있다. 이 파라미터는 REST API를 호출할 때 query string으로 전달되며 복수의 key-value 쌍이 된다. script body 내에서는 Javascript를 이용할 수 있으며, Javascript 1.7 문법을 지원한다. 단, 일부의 제한사항이 있으며, 자세한 내용은 제한에서 다룬다.

리턴으로 지정한 변수는 REST 호출의 결과 Response에서 확인할 수 있다(call_return의 value). 리턴이 가능한 타입은 String, Number, Boolean, null, Object, Array이며 Object는 nesting이 가능하다.

  • Script 정의 Example:
function levelup_item(params) {

	// 아이템 강화 : sword + 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
    }
}

Script의 실행

정의한 Script는 다음과 같은 방법으로 실행될 수 있다.

  • REST API를 사용하여 실행한다. REST API의 Script 실행를 참조한다.
  • 메일의 reward 받기 추가해야 함!!!
  • Google, Apple, Naver 결제 완료 API를 호출하면 이와 연결된 스크립트가 실행된다. 보통 이 스크립트에는 결제가 완료된 후 아이템을 생성하거나 증가시키는 등의 작업을 수행하게 된다. 결제 완료와 관련된 내용은 API 문서에서 네이버 결제완료, Google 결제완료, Apple 결제완료를 참조한다.

Global functions

require(scriptName)

공용으로 쓰일 함수나 상수를 따로 스크립트로 정의하고 이를 포함시켜 사용하기 위해서 require를 사용한다. scriptName은 string으로, 콘솔에서 정의된 스크립트의 이름이다.

  • Example:
require("user");

##제공되는 라이브러리 Script에서 사용할 수 있도록 제공되는 Library는 다음과 같다.

  • HObject : Hive5 object의 생성과 삭제, 값을 읽어오거나 저장하는 함수들
  • HDataTable : 콘솔에서 정의한 Data Table을 Script에서 사용할 수 있도록 하는 함수들
  • HSecurity : 데이터 보안을 위한 암호화, 메세지 다이제스트(message digest) 관련 함수들
  • HDate : TimeZone이 반영된 날짜와 시간 관련 함수
  • HLeaderboard : 리더보드와 관련된 함수들
  • HMail : Mail과 관련된 함수들
  • HUserLib : User Library와 관련된 함수들
  • HNotification : 친구 등 다른 사용자에게 메세지를 보낼 수 있는 통지와 관련된 함수들
  • HAppCounter : 게임 앱 전체 사용자에게 공유되는 Counter
  • HLogger : Log 기록과 관련된 함수
  • HFriend : Friend 관련 함수
  • HPlayer : 사용자(Player) 관련 함수
  • HCoupon : Coupon 관련 함수
  • HForum : Forum 관련 함수
  • HSharedObject : Hive5 shared object의 생성과 삭제, 값을 읽어오거나 저장하는 함수들

###HObject

Hive5 Object의 생성과 삭제, 값을 읽어오거나 저장하는 함수들이다. Hive5 Object는 Hive5 시스템에서 사용하는 데이터 구조로, javascript의 Object 타입을 확장한 것이다. javascript의 Object와 동일하게 동적으로 필드를 추가, 삭제할 수 있고 그 내용을 바꿀 수 있다. 또한 현재의 Object 값을 서버에 영구히 저장할 수 있고, 언제든지 다시 불러올 수 있다. 게임과 관련된 각종 정보들을 서버에 저장하고, 각종 판정 등에 이를 사용할 수 있다.

Hive5 Object의 생성은 key 이름을 지정하는 방법과 지정하지 않는 방법이 있다. key 이름을 지정하면, 지정된 key 이름으로 다시 불러오거나 삭제할 수 있다. key 이름을 따로 지정하지 않으면, 서버에서 고유한 값을 발급하며 getKey() 함수로 확인할 수 있다. 이하 Hive5 Object를 object로 표현하기로 한다. Javascript의 Object와 혼동을 피하기 위해서 이는 명시적으로 Javascript Object로 지칭할 것이다.

create([key])

object를 생성해 리턴한다. key는 string으로, load 할 때 사용된다. key는 영대소문자와 숫자가 가능한데, 첫글자는 영문자로 시작해야 한다. key를 지정하지 않으면, 고유한 값을 생성해서 자동으로 할당한다. 생성된 key는 리턴된 object의 getKey() 메서드를 이용하거나, _key 프로퍼티 값으로 확인할 수 있다.

  • Example:
var player = HObject.create("user");

destroy(key)

생성된 object를 소멸시킬 때 사용한다. 소멸시킬 object의 key를 넘긴다. 생성되지 않는 객체를 소멸시키려고 하면 에러가 발생한다(Error Code 참조).

  • Example:
HObject.destroy("user");

destroy(keys)

복수의 object를 소멸시킬 때 사용한다. keys는 소멸시킬 object key의 array다.

  • Example:
HObject.destroy(["user", "inventory", "game"]);

load(key)

생성된 object를 불러올 때 사용한다. 불러올 object의 key를 넘기면 해당 object의 값이 Javascript의 Object 타입으로 리턴된다. 없는 객체라면 에러가 발생한다(Error Code 참조).

  • Example:
var player = HObject.load("player");

load(keys)

생성된 object들을 불러올 때 사용한다. 불러올 object의 key들의 array를 넘기면 해당 object의 값들이 Javascript의 Array 타입으로 리턴된다. 주의할 점은 결과의 array가 요청할 때 사용된 keys의 순서를 보장하지 않는다는 사실이다. 결과값에 object._key를 확인하거나, 필요하다면 특정값으로 소팅해야 한다.

  • Example:
var items = HObject.load(["12231213", "1232134", "32423423"]);  //create로 생성된 object의 key들

loadOrCreate(key)

key에 해당하는 object가 이미 생성되었으면 load를 하고, 없으면 새로 생성해 리턴한다.

exists(key)

key에 해당하는 object가 생성되었는지의 여부를 리턴한다.

save(object)

불러온 object의 필드값들을 변경한 후, 변경 내용이 서버에 반영되도록 저장할 때 사용한다. load의 결과로 받은 객체를 넘기게 된다. 만약 이 객체의 _key 필드를 변경하면, save 대상 객체가 바꾸어지므로 주의해야 한다. 이렇게 대상을 변경하였는데, 그 대상 객체가 없는 경우라면 에러가 발생한다.

특정 필드를 삭제하고 싶은 경우에는 그 필드를 delete 한다. 한편, HObject.save(obj)는 obj.save()로 호출해도 동일한 동작을 수행한다.

  • Example:
var player = HObject.create("player");
player.coin = player.coin + 1;
player.save(); //HObject.save(player)와 동일하다.

var bomb = HObject.create("bomb");
delete bomb.flag;		// flag 필드를 삭제하게 됨
HObject.save(bomb);

save(objects)

objects는 object의 array다. 복수개의 object들을 동시에 save할 때 사용한다. HObject.load()와 HObject.save()가 여러 번 호출되면 수행시간이 길어지므로, 이 메서드를 활용하면 퍼포먼스가 좋다.

  • Example:
var items = HObject.load(["12231213", "1232134", "32423423"]);  //create로 생성된 object의 key들
items = items.map(function (item) {
  item.exp = 0;
  return item;
});
HObject.save(items);

loadByUser({platform:platformName, id:userid}, key)

자신의 object가 아닌 친구나 다른 사람의 object를 불러올 수 있다. 친구의 메달 수를 조회한다거나, 친구의 인벤토리를 조회할 때 유용하다.

  • Example:
var friendMedal = HObject.loadByUser({platform:"google", id:"12345"}, "medal");

loadByUser({platform:platformName, id:userid}, keys)

자신의 object가 아닌 친구나 다른 사람의 object를 불러올 수 있다. keys는 object key의 Array다. 친구의 아이템들을 조회하는 등의 용도로 유용하다. 여기서도 결과의 array는 keys에서 지정된 순서를 보장하지 않는다는 점을 주의해야 한다.

  • Example:
var friendMedal = HObject.loadByUser({platform:"google", id:"12345"}, ["medal", "user"]);

loadByUsers([{platform:platformName, id:userid}, ...], key)

자신의 object가 아닌 친구나 다른 사람들의 object를 불러올 수 있다. 친구들 전체에 대해 이름이나, 메달 수 등을 조회할 때 유용하다.

  • Example:
var friendMedal = HObject.loadByUser([{platform:"google", id:"12345"}, {platform:"google", id:"12346"}], "medal");
Object 함수들을 이용한 Example
// 아이템 구매
function buyItem(index) {
    //params
    //index : 구매하려는 아이템의 고유번호(character table에 정의)
    // index를 갖는 아이템 object를 생성하여, 인벤토리에 저장한다.

    var player = HObject.load("player");
    var tbl = HDataTable.load("item", {index:parseInt(index)});

    if (tbl.length!=1)
        return "일치조건 없음";

    var target = tbl[0];

    if (player.coin<target.price)
        return "코인부족";

    var item = HObject.create();
    item.type = "item";
    item.index = target.index;
    item.save();

    player.item_inv.push({id:item.getKey(), index:item.index});
    player.coin -= target.price;
    player.save();

    return player;
}

###HDataTable

Hive5 콘솔에서 게임과 관련한 규칙이나 속성들을 Data Table로 저장할 수 있다. 이 테이블을 Script에서 사용할 수 있도록 Javascript 객체로 변환하는 함수다.

load(tableName[, condition])

콘솔에서 정의한 Data Table의 값들을 script에서 사용할 수 있도록 가져온다. 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}
]
HDataTable 사용하는 예
//경험치가 증가하여 레벨을 증가시킬 때 테이블을 참조
function increase_level_with_exp(params)

    // table 로딩
    var tbl = HDataTable.load("exp_level");

	var player = HObject.load("player");

    // 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;
        }
    }

}

###HSecurity

데이터 보안을 위한 암호화, 메세지 다이제스트(message digest) 관련 함수들

sha1(str)

SHA-1(Secure Hash Algorithm 1) 알고리즘을 이용하여 str으로 넘긴 데이터를 변환한다.

클라이언트에서 script를 실행하기 위해 점수 등을 넘겨야 되는 경우가 있다. 이 때 점수가 평문(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";
}

sha256(str)

SHA-256 알고리즘을 이용하여 str으로 넘긴 데이터를 변환한다.

hmacSha1(str, key, base64encoding)

HMAC-SHA1 알고리즘을 이용하여 str으로 넘긴 데이터를 key를 이용해 변환한다. base64encoding을 true로 하면 Base64 인코딩된 결과를 문자열로 받게 되며, false로 하면 hex로 표현된 문자열로 받는다.

hmacSha256(str, key, base64encoding)

HMAC-SHA256 알고리즘을 이용하여 str으로 넘긴 데이터를 key를 이용해 변환한다. base64encoding을 true로 하면 Base64 인코딩된 결과를 문자열로 받게 되며, false로 하면 hex로 표현된 문자열로 받는다.

md5(str)

MD5(Message-Digest algorithm 5) 알고리즘을 이용하여 str으로 넘긴 데이터를 변환한다.

HDate

콘솔에서 App에 대해 TimeZone을 설정할 수 있다. 이 TimeZone이 반영된 날짜와 시간을 얻는 함수들이다.

getYear()

연도를 가져온다. 리턴된 값은 실제 연도 값에서 1900을 뺀 값이다.

getMonth()

월을 가져온다. 리턴된 값은 1월이 0이며, 12월이 11이다.

getDate()

일을 가져온다.

getDay()

요일을 가져온다. 0이 일요일이며, 1은 월요일이다. 6이 토요일이다.

getHours()

시간을 가져온다. TimeZone이 반영된 로컬 시간이다. TimeZone은 콘솔에서 설정한다.

getMinutes()

분을 가져온다.

getSeconds()

초를 가져온다.

###HLeaderboard

리더보드와 관련된 함수들

submitScore(leaderboardKey, score[, extras[, forceUpdate]])

리더보드에 스코어를 제출할 때 사용한다. leaderboardKey는 관리콘솔에서 생성한 리더보드의 Key이며, score는 득점한 점수값이다. 리더보드 id가 유효하지 않는 경우에는 에러가 발생한다(Error Code 참조). extras는 추가 데이터로 어떤 type이라도 지정할 수 있다. 기본값은 null이다. forceUpdate는 boolean이며, true 인 경우에는 이전 score보다 점수가 낮더라도 강제로 최고 점수로 업데이트 한다. 생략할 경우 false다.

리더보드를 생성할 때 scoring mode에 따라서 최종 점수 계산이 달라진다. 높은 점수(high) 방식이면 제출한 점수가 이전보다 높아야지 기록이 갱신된다. 최종 점수(last) 방식은 제출할 때 마다 최종 점수로 인식한다. 누적 점수(cumulative) 방식은 제출한 점수가 기존의 점수에 합산된다.

listGlobalScores(leaderboardKey, rankMin, rankMax[, objectClasses])

글로벌 랭킹을 조회한다. rankMin은 1부터 시작하는 순위이므로 1보다 작은 값을 전달하면 안된다. 가져올 수 있는 최대 개수는 20개여서, rankMax가 더 커도 무시된다. 값 조회 결과에 사용자들의 Object를 같이 조회하고 싶은 경우에는, string array 형태로 object의 class 이름을 objectClasses에 넣어준다.

HLeaderboard.listGlobalScores("arena", 1, 10, ["sword", "heart"]);

listGlobalScores(leaderboardKey, rankMin, rankMax, rangeMin, rangeMax[, objectClasses])

글로벌 랭킹 조회 시에 특정 점수 범위로 국한시켜서 조회한다.

listSocialScores(leaderboardKey[, objectClasses])

소셜 랭킹을 조회한다. 조회 결과에 사용자들의 Object를 같이 조회하고 싶은 경우에는, string array 형태로 object의 class 이름을 objectClasses에 넣어준다.

listGlobalScoresForLastSeason(leaderboardKey, rankMin, rankMax[, objectClasses])

지난 시즌의 글로벌 랭킹을 조회한다.

listGlobalScoresForLastSeason(leaderboardKey, rankMin, rankMax, rangeMin, rangeMax[, objectClasses])

지난 시즌의 글로벌 랭킹 조회 시에 특정 점수 범위로 국한시켜서 조회한다.

listSocialScoresForLastSeason(leaderboardKey[, objectClasses])

지난 시즌의 소셜 랭킹을 조회한다.

getMyRank(leaderboardKey)

내 등수 정보를 얻어온다. 'rank'에 자신의 등수가, 'total'에 전체 수가, 'score'에 점수가 있다. 단, 점수 기록이 없는 경우에 'rank'는 'null'이 된다.

getMyRankForLastSeason(leaderboardKey)

지난 시즌의 내 등수 정보를 얻어온다. 'rank'에 자신의 등수가, 'total'에 전체 수가, 'score'에 점수가 있다. 단, 점수 기록이 없는 경우에 'rank'는 'null'이 된다.

getInfo(leaderboardKey)

Leaderboard의 정보를 얻어온다. 결과는 다음과 같은 json이다.

{
    "id": 19876,
    "name": "Loeaderboard for test",
    "order": "larger_is_better",
    "reset_info": {
        "minute": 1,
        "hour": 1,
        "last_reset_at": "2014-07-07T01:01:00",
        "weekday": "mon",
        "period": "weekly"
    }
}

count(leaderboardKey)

현재 시즌에 점수가 등록된 총 플레이어 수를 리턴한다.

countForLastSeason(leaderboardKey)

지난 시즌에 점수가 등록된 총 플레이어 수를 리턴한다.

###HMail

Mail과 관련된 함수들

create(content, extras[[, tags], rewardScript, scriptParams])

메일을 생성한다. content는 내용으로 string이며, extras는 추가적인 데이터로 어떤 type도 가능하다. tag를 붙이고자 할때는 array 타입의 tag를 parameter로 넘긴다. mail에 보상(reward)을 부여할 수도 있다. 보상은 미리 만들어진 script를 실행해서 효과를 낸다. rewardScript는 이 script의 이름이며, scriptParams는 이 script에 전달할 마라미터로 Object type이다.

  • Example:
HMail.create("test mail", {item_id:12}, ["tag1", "tag2"], "put_item", {item_id:12});

send({platform:platformName, id:user_id}, content, extras[[, tags], rewardScript, scriptParams])

친구에게 메일을 보낼 때 사용한다. 친구의 platform과 id를 지정할 수 있고, content는 내용으로 string이며, extras는 추가적인 데이터로 어떤 type도 가능하다. tag를 붙이고자 할때는 array 타입의 tag를 parameter로 넘긴다. mail에 보상(reward)을 부여할 수도 있다. 보상은 미리 만들어진 script를 실행해서 효과를 낸다. rewardScript는 이 script의 이름이며, scriptParams는 이 script에 전달할 마라미터로 Object type이다.

  • Example:
HMail.send({platform:"none", id:"1234"}, "test mail", {flag:true}, ["tag1", "tag2"]);

count([tag])

메일의 개수를 얻어온다. tag는 특정 태그가 붙은 메일의 개수만 가져온다.

list(order[, offset[, limit[, tag]]])

메일 목록을 얻어온다. order는 "asc", "dec" 중의 하나 값을 가질 수 있으며, "asc"는 오랜 메일부터, "dec"는 새로운 메일부터 가져온다. offset은 가져올 메일의 위치를, limit은 가져올 메일 개수를 지정한다. limit은 최대 20이며 default도 20이다.

delete(mailId)

id가 mailId인 메일을 삭제한다.

###HUserLib

User Library와 관련된 함수들

require(libName)

콘솔에서 정의한 User Library를 사용할 수 있도록 로드한다. 유저라이브러리는 javascript 기반의 함수나 global로 사용할 상수 등을 포함할 수 있다.

  • Example:
HUserLib.require("quest_lib");

requireOnce(libName)

콘솔에서 정의한 User Library를 사용할 수 있도록 로드한다. require()와의 차이는 동일한 라이브러리에 대해서 여러 번 호출하여도 한 번만 로드되는 것이 보장된다.

  • Example:
HUserLib.requireOnce("quest_lib");

###HNotification

친구 등 다른 사용자에게 메세지를 보낼 수 있는 통지와 관련된 함수들로 친구에게 선물하기 등을 구현할 수 있다.

send({platform:platformName, id:user_id}, type, msg)

platformName 플랫폼의 user_id를 가진 사용자에게 msg를 보낸다. type은 string으로 특정 type만 receive할 수 있도록 지정할 수 있다. msg는 어떤 타입이라도 올 수 있다.

*example:

// 선물하기 메세지를 보내는 예
HNotification.send({platform:"none", id:"1234"}, "gift", {type:"gift", param1:"heart", param2:"1"});

receiveAll()

자신에게 온 msg를 모두 수신한다. send를 통해 보내진 데이터들을 Array형태로 리턴받는다. 한 번 수신을 하면 삭제되므로, receiveAll()을 다시 호출하면 이미 수신한 메세지는 더이상 포함되지 않는다. send()에서 파라미터로 넘긴 type은 따로 리턴되지 않으므로, 분류가 필요한 경우에는 아래의 예처럼 메세지의 필드를 이용해야 한다. 수신하지 않은 메세지는 영구히 보관되지 않고, 한 달이 지나면 자동 삭제된다.

*example:

// 수신 메세지에서 선물하기를 받았는지 확인하고 하트 증가
var msgs = HNotification.receiveAll();
for (var i=0; i<msgs.length; i++) {
	var msg = msgs[i];
    if (msg.type=="gift") {
    	if (msg.param1 =="heart") {
            var user = HObject.load("user");
            user.heart += msg.param2;
            HObject.save(user);
        }
    }
}

receive(type)

send()때 지정한 type을 갖는 메세지만 모두 수신한다.

###HAppCounter

게임 앱 전체 사용자에게 공유되는 Counter. 게임 내에서 선착순 n명에게 보상을 지급하는 이벤트 등에 유용하다. 사용가능한 카운터의 개수는 앱당 10개로 제한되며, 관리 콘솔에서 추가, 삭제할 수 있다.

increase(counterName)

해당 이름을 가진 카운터를 1 증가시킨다. 리턴 값으로 변경된 값을 받는다. 없는 카운트 이름이면 0의 초기값을 갖는 카운터를 새로 생성한 후 증가된다.

increaseBy(counterName, increment)

해당 이름을 가진 카운터를 increment 만큼 증가시킨다. 리턴 값으로 변경된 값을 받는다. 없는 카운트 이름이면 0의 초기값을 갖는 카운터를 새로 생성한 후 증가된다.

decrease(counterName)

해당 이름을 가진 카운터를 1 감소시킨다. 리턴 값으로 변경된 값을 받는다. 없는 카운트 이름이면 0의 초기값을 갖는 카운터를 새로 생성한 후 증가된다.

decreaseBy(counterName, decrement)

해당 이름을 가진 카운터를 decrement 만큼 감소시킨다. 리턴 값으로 변경된 값을 받는다. 없는 카운트 이름이면 0의 초기값을 갖는 카운터를 새로 생성한 후 증가된다.

get(counterName)

해당 이름을 가진 카운터의 현재 값을 가져온다.

HAppCounter를 사용하는 예

// 선착순 100명에게 보상
var count = HAppCounter.increase("dungeon_event1");
if (count<=100) {
	// 보상을 수행함
    var user = HObject.load("user");
    user.gold += 100;
    HObject.save(user); 
    return {reward:true, msg:count+"번 째로 입장하여 선착순 100명 미션을 달성하셨습니다! 100골드를 지급합니다."};
}
else {
    return {reward:false, msg:count+"번 째로 입장하여 선착순 100명 미션 달성에 실패했습니다."};
}

###HLogger

Log 기록과 관련된 함수

log(msgType, msg)

플레이어별로 로그를 기록할 수 있다. 콘솔에서 플레이어별로 기록된 로그의 열람이 가능하며, msgType으로 필터링이 가능하다. 아이템 구매 내역 기록 등의 용도로 유용하다.

*Example:

HLogger.log("items", "황금폭탄 구매(590gold)");

list([msgType, ] offset, limit)

로그를 조회한다. internal에서만 불리운다.

count([msgType])

로그의 개수를 세어온다.

###HFriend

Friend와 관련된 함수

list([group])

친구들의 목록을 조회한다. 특정 그룹의 친구를 조회하고자 하는 경우에는 그룹의 이름을 parameter로 넘겨준다.

*Example:

HFriend.list();

update(group, friends)

특정 그룹 'group'의 친구목록을 'friends'로 교체한다. friends는 {platform:platformName, id:user_id}의 array다.

*Example:

HFriend.update('default', [{platform:'kakao', id:'1235d23e'}, {platform:'kakao', id:'xxdf1232123'}]);

add(group, friends)

특정 그룹 'group'의 친구목록에 'friends'를 추가한다. friends는 {platform:platformName, id:user_id}의 array다.

*Example:

HFriend.add('default', [{platform:'kakao', id:'1235d23e'}, {platform:'kakao', id:'xxdf1232123'}]);

addSymmetrically(group, {platform:platformName, id:user_id}[, maxFriendSize])

특정 그룹 'group'에 friend를 추가한다. 이때, 서로 친구가 되도록 한다. 이미 그룹에 maxFriendSize 만큼의 친구가 둘 중 한명이라도 있게되면 exception이 발생한다. exception은 TooManyFriendsException이고, error code는 2705이다.

remove(group, friends)

특정 그룹 'group'의 친구목록에서 'friends'를 삭제한다. friends는 {platform:platformName, id:user_id}의 array다.

*Example:

HFriend.remove('default', [{platform:'kakao', id:'1235d23e'}, {platform:'kakao', id:'xxdf1232123'}]);

removeSymmetrically(group, {platform:platformName, id:user_id})

상호 친구 관계를 삭제한다.

count([group])

친구 수를 센다. group을 설정하면 해당 group내의 친구만 센다.

count({platform:platform, id:id}, [group])

특정 player의 친구 수를 센다. group을 설정하면 해당 group내의 친구만 센다.

###HPlayer

Player와 관련된 함수

findByNickname(nickname)

nickname으로 player를 찾는다. 결과로 "platform"과 "id"가 포함된다.

*Example:

HPlayer.findByickname('nickname_1');

###HCoupon

Coupon과 관련된 함수

get(serial)

serial로 발급된 쿠폰 정보를 얻어온다. 다음 항목이 결과에 포함된다. campaign_id, serial, valid_from, valid_to

invalidate(serial)

serial로 발급된 쿠폰을 무효화한다. 무효화를 할때는, 쿠폰과 연계된 'call'을 실행시키지 않는다.

###HForum

Forum과 관련된 함수. Forum의 생성은 콘솔에서 수행한다.

listThreads(forumKey[, order[, offset[,limit]]])

포럼에 등록된 글들을 가져온다. forumKey는 콘솔에서 정의한 포럼의 key로 string이며, order는 가져올 글의 순서로 "asc"는 오래된 글부터, "dec"는 새 글부터 가져온다. default는 "dec"다. offset는 가져올 글의 위치, limit은 개수다. 각각 default는 0과 20이다. limit은 최대 20만 지원된다.

countThreads(forumKey)

포럼에 등록된 글들의 개수를 가져온다. forumKey는 콘솔에서 정의한 포럼의 key로 string이다.

createThread(forumKey, title, content, extras)

포럼에 글을 등록한다. forumKey는 콘솔에서 정의한 포럼의 key로 string이다. title과 content는 제목과 내용으로 string이다. extras는 추가 데이터로 어떤 type도 가능하다.

updateThread(forumKey, threadId, title, content, extras)

포럼에 등록된 글을 수정한다. forumKey는 콘솔에서 정의한 포럼의 key로 string이다. threadId는 string으로 글의 id다. title, content, extras는 각각 제목, 내용, 추가 데이터다.

deleteThread(forumKey, threadId)

포럼에 등록된 글을 삭제한다. forumKey는 콘솔에서 정의한 포럼의 key로 string이다. threadId는 string으로 글의 id다.

###HSharedObject

HObject는 플레이어별로 생성되고 관리되는 object다. HObject를 통해서도 다른 플레이어의 object를 읽어올 수 있지만, save는 불가능하다. 반면, shared object는 모든 플레이어가 읽거나 쓸 수 있다. 단, 동시성(concurrency)문제에 주의해야 한다. (save 항목 참조)

Shared object도 HObject와 같이 key 이름을 지정하는 생성과 지정하지 않는 생성이 있다. key 이름을 지정하지 않으면, 서버에서 고유한 값을 발급하며 getKey() 함수로 확인할 수 있다.

create([key])

Shared object를 생성해 리턴한다. key는 string 타입이며, load 할 때 사용된다. key는 영대소문자와 숫자가 가능한데, 반드시 첫글자는 영문자로 시작해야 한다. key를 지정하지 않으면, 고유한 값을 생성해서 자동으로 할당한다. 생성된 key는 리턴된 object의 getKey() 메서드를 이용하거나, _key 프로퍼티 값으로 확인할 수 있다.

destroy(key)

생성된 shared object를 소멸시킬 때 사용한다. 소멸시킬 shared object의 key를 넘긴다. 존재하지 않는 객체를 소멸시키려고 하면 exception이 발생한다(Error Code 참조).

destroy(keys)

복수의 shared object를 소멸시킬 때 사용한다. keys는 소멸시킬 object key의 array다.

load(key)

생성된 shared object를 불러올 때 사용한다. 불러올 shared object의 key를 넘기면 해당 shared object의 값이 Javascript의 Object 타입으로 리턴된다. 없는 객체라면 exception이 발생한다(Error Code 참조).

load(keys)

생성된 shared object들을 불러올 때 사용한다. 불러올 shared object의 key들을 array로 넘기면 해당 object의 값들이 Javascript의 Array 타입으로 리턴된다. 주의할 점은 결과의 array가 요청할 때 사용된 keys의 순서를 보장하지 않는다는 사실이다. 결과값에 object._key를 확인하거나, 필요하다면 특정값으로 소팅해야 한다.

loadOrCreate(key)

key에 해당하는 shared object가 이미 생성되었으면 load를 하고, 없으면 새로 생성해 리턴한다.

exists(key)

key에 해당하는 shared object의 존재 여부를 리턴한다.

save(object[, exceptionHandler])

불러온 shared object의 필드값들을 변경한 후, 변경 내용이 서버에 반영되도록 저장할 때 사용한다. load의 결과로 받은 객체를 넘기게 된다. 만약 이 객체의 _key 필드를 변경하면, save 대상 객체가 바꾸어지므로 주의해야 한다. 이렇게 대상을 변경하였는데, 그 대상 객체가 없는 경우라면 exception이 발생한다.

특정 필드를 삭제하고 싶은 경우에는 그 필드를 delete 한다. 한편, HSharedObject.save(obj)는 obj.save()로 호출해도 동일한 동작을 수행한다.

shaed object는 여러 플레이어에 의해 동시에 load하고 save하므로 동시성 문제가 발생할 수 있어 주의가 필요하다. A라는 사용자가 shared object를 불러온 후 값을 변경해 save하는 상황을 가정할 때, save 직전에 B라는 사용자가 이 shared object를 변경해 저장할 수 있다. 이후 A에 의해 save가 되면 B가 save한 내용에 덮어 쓰게되어 문제가 발생한다. 이런 상황이 발생하면, exceptionHandler의 지정여부에 따라 다음과 같이 동작한다.

  1. exceptionHandler를 지정하지 않고 생략한 경우에는 exception이 발생한다.
  2. exceptionHandler를 함수로 넘길 경우 이 함수가 수행된다.
  3. exceptionHandler를 null로 넘길 경우 exception을 무시하고 강제로 덮어쓴다.

*Example:

var monsters = HSharedObject.load("monsters");
var monster = items.deck.pop();

var result = true;
var message = "";

HSharedObject.save("items", function() {
  // 다른 사용자에 의해 이미 변경된 경우
  result = false;
  message = "다른 유저가 이미 몬스터를 제거했습니다.";
});

increase(key, field, increment)

이후의 함수들은 load(), save()를 호출하는 형태가 아니라 하나의 함수에서 load와 save가 동시에 발생하여 atomic transaction을 지원한다. increase는 shared object의 특정 필드를 증가시킨다. 이 필드는 number type이어야 하며, 아닐 경우에는 에러가 발생한다. key는 object의 key이고, field는 필드의 이름이며, increment는 증가값으로 number type이다. 증가된 필드의 값이 리턴된다.

decrease(key, field, increment)

이 함수는 atomic transaction을 지원한다. shared object의 특정 필드를 감소시킨다. 이 필드는 number type이어야 하며, 아닐 경우에는 에러가 발생한다. key는 object의 key이고, field는 필드의 이름이며, decrement는 감소값으로 number type이다. 감소된 필드의 값이 리턴된다.

push(key, field, value)

이 함수는 atomic transaction을 지원한다. shared object의 특정 array type 필드에 push를 수행한다(Array.prototype.push). 즉, 배열 뒷쪽에 value가 추가된다. key는 object의 key이고, field는 필드의 이름이며, value는 push할 내용으로 어떤 타입이라도 가능하다. push한 결과의 array 내용이 리턴된다.

pop(key, field, count)

이 함수는 atomic transaction을 지원한다. shared object의 특정 array type 필드에 pop을 수행한다. 즉, 배열의 뒷쪽에서 count만큼의 element를 꺼낸다. 꺼내고 남은 배열이 object에 저장된다. key는 object의 key이고, field는 필드의 이름이며, count는 꺼내올 element의 개수다. 꺼내온 결과가 array로 리턴된다.

unshift(key, field, value)

이 함수는 atomic transaction을 지원한다. shared object의 특정 array type 필드에 unshift를 수행한다(Array.prototype.unshift). 즉, 배열 앞쪽에 value가 추가된다. key는 object의 key이고, field는 필드의 이름이며, value는 어떤 타입이라도 가능하다. unshift한 결과의 array 내용이 리턴된다.

shift(key, field, count)

이 함수는 atomic transaction을 지원한다. shared object의 특정 array type 필드에 shift를 수행한다. 즉, 배열의 앞쪽에서 count만큼의 element를 꺼낸다. 꺼내고 남은 배열이 object에 저장된다. key는 object의 key이고, field는 필드의 이름이며, count는 꺼내올 element의 개수다. 꺼내온 결과가 array로 리턴된다.

Script에서 발생하는 Error

스크립트와 관련된 에러는 크게 Javascript 내에서 일어나는 Runtime 에러와 Hive5의 Library나 구조에서 발생되는 에러가 있다.

1. Javascript script에서 발생하는 exception

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에 정의되어 있다.

###3. Error 발생으로 인한 rollback 스크립트를 수행하다 에러가 발생할 경우, 같은 스크립트 내에서의 기존 작업들은 모두 rollback되어 수행전과 동일한 상태가 된다. 다음 스크립트를 살펴보자.

var user = HObject.load("user");
user.exp++;
user.save();

var boss = HObject.load("boss"); // boss가 정의되어 있지 않아 여기서 exception 발생
return boss;

이 스크립트가 순차적으로 수행되어 user.save()까지는 성공적으로 수행되었다고 가정하자. 그 다음 HObject.load("boss")에서는 boss라는 key의 object가 생성되어 있지 않아 예외가 발생했다. user object의 save가 성공했을지라도 예외 발생으로 인해 이전까지의 모든 작업은 rollback이 된다.

[주의] HSharedObject를 사용하는 경우에는 주의가 필요하다. HSharedObject의 경우에도 예외가 발생하면 rollback이 된다. 그러나 rollback이 수행되기 전에 다른 플레이어에 의해 같은 shared object가 update되었다면, 이 값이 유효하므로 rollback을 수행할 수 없게 된다. HSharedObject를 사용해야 하는 경우에는 여러 스크립트로 나누는 방법 등으로 간결함을 유지해 예외 발생 가능성을 최대한 줄이는게 바람직하다.

Error Code

API 문서의 error code 참고

##제한

1. Array type에서의 key 제한

  • 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);

2. Return의 제한

  • 리턴 타입으로는 Number, String, Boolean, null, Array, Object가 가능하다. Object는 nesting이 가능하다. function을 리턴할 경우 에러가 발생한다. Number type인 경우에도 NaN이나 Infinity를 리턴할 경우 에러가 발생한다.

3. 환경의 제한

수행시간은 다음과 같은 제한이 있다.

  • 수행시간: 1000 ms 까지 허용

API

Script 실행

  • Path: /:version/scripts/run/:name
  • Authentication Header: X-APP-KEY, X-AUTH-UUID, X-AUTH-TOKEN
  • Method: POST
  • Request Parameter:
    Name Type Description
    name String script name

script에 전달할 parameter는 json body의 params 필드에 정의한다.

{"params":{ "param1":"aaa", "param2":"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 script 실행의 결과. call을 정의하는 것에 따라서 이 값의 type도 변경되니 유의

Script 실행 (no authentication)

player 인증 전에 script 실행이 필요할 때 사용합니다.

  • Path: /:version/scripts/check/:name
  • Authentication Header: X-APP-KEY, X-AUTH-UUID
  • Method: POST
  • Request Parameter:
    Name Type Description
    name String script name

Clone this wiki locally