Skip to content

Sample Procedures (v5)

Artie Choi edited this page Jun 2, 2014 · 5 revisions

##init_player hornet.hive5.io/v5/procedures/call/init_player

로그인 때 호출한다. 최초 로그인인 경우에 디폴트값으로 초기화하고 플레이어 정보를 저장한다. 예제에서는 캐릭터 3종과 무기 아이템 3종을 생성해 각각 인벤토리에 보관하고, 각 캐릭터에 무기를 장착한다.

// 최최로 로그인 되는 상황 처리
// 최초 로그인인 경우 player를 초기화시켜주고, 기본 캐릭터와 아이템들도 저장한다

player = HObject.load("player");  //singleton

if (player.level == null) { // 최초 생성이라는 의미

    //각종초기화..
    player.level = 1;
    player.exp = 0;
    player.score = 0;
    player.gold = 10;
    player.coin = 400;
    
    // 기본 무기 생성
    weapon1 = HObject.create("item");
    weapon1.index = 1; // 아이템의 고유번호. 1, 2, 3이라 가정 (items table)
    weapon1.type = "weapon"; // table 통해 확인가능하지만, 자주 쓰는 것들은 필드로 지정함
    weapon1.equipped = true; // 장착여부
    weapon2 = HObject.create("item");
    weapon2.index = 2;
    weapon2.type = "weapon";
    weapon2.equipped = true;
    weapon3 = HObject.create("item");
    weapon3.index = 3;
    weapon3.type = "weapon";
    weapon3.equipped = true;
    HObject.save(weapon1);
    HObject.save(weapon2);
    HObject.save(weapon3);
    
    // 기본 캐릭터
    char1 = HObject.create("character");
    char1.index = 1;       // 기본 캐릭터. 고유넘버가 1,2,3이라고 가정 (character table참조)
    char1.weapon = weapon1.id; //instance id
    char2 = HObject.create("character");
    char2.index = 2;
    char2.weapon = weapon2.id;
    char3 = HObject.create("character");
    char3.index = 3;
    char3.weapon = weapon3.id;
    HObject.save(char1);
    HObject.save(char2);
    HObject.save(char3);
    
    // 아이템 인벤토리
    player.item_inv = [{id:weapon1.id, index:weapon1.index}, {id:weapon2.id, index:weapon2.index}, {id:weapon3.id, index:weapon3.index}];
    
    // 캐릭터 인벤토리
    player.char_inv = [{id:char1.id, index:char1.index}, {id:char2.id, index:char2.index}, {id:char3.id, index:char3.index}];
    
    HObject.save(player);
    return player;
}

return "already created";

*결과 예

{
    "result_code": 0,
    "call_return": {
        "gold": 10,
        "score": 0,
        "char_inv": [
            {
                "id": "3391827170368553",
                "index": 1
            },
            {
                "id": "3391827173121065",
                "index": 2
            },
            {
                "id": "3391827175414825",
                "index": 3
            }
        ],
        "exp": 0,
        "id": null,
        "item_inv": [
            {
                "id": "3391827144285225",
                "index": 1
            },
            {
                "id": "3391827146710057",
                "index": 2
            },
            {
                "id": "3391827148545065",
                "index": 3
            }
        ],
        "coin": 400,
        "class": "player",
        "level": 1
    }
}

##buy_item hornet.hive5.io/v5/procedures/call/buy_item?index=4

아이템을 구매한다. 구매하려는 아이템의 index를 넘긴다. 아이템의 인덱스와 속성은 item 데이터 테이블에 정의되어 있다.

//params
//index : 구매하려는 아이템의 고유번호(character table에 정의)

// index를 갖는 아이템 인스턴스를 생성하여, 인벤토리에 저장한다.

var player = HObject.load("player");
var tbl = DataTable.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;

*결과 예:

{
    "result_code": 0,
    "call_return": {
        "gold": 10,
        "score": 0,
        "char_inv": [
            {
                "id": "3391864164588585",
                "index": 1
            },
            {
                "id": "3391864167210025",
                "index": 2
            },
            {
                "id": "3391864169897001",
                "index": 3
            }
        ],
        "exp": 0,
        "id": null,
        "item_inv": [
            {
                "id": "3391864130968617",
                "index": 1
            },
            {
                "id": "3391864133721129",
                "index": 2
            },
            {
                "id": "3391864136277033",
                "index": 3
            },
            {
                "id": "3391871961406505",
                "index": 4
            }
        ],
        "coin": 200,
        "class": "player",
        "level": 1
    }
}

##equip_weapon hornet.hive5.io/v5/procedures/call/equip_weapon?weapon_id=3391871961406505&char_id=3391864164588585

인벤토리에 있는 아이템을 장착한다. 장학대상 캐릭터와 장착 아이템을 넘기면 장착으로 데이터를 변경해 저장한다.

//params
//weapon_id : 장착하려는 무기 인스턴스 id
//char_id : 장착 대상 캐릭터 인스턴스 id

// instance 없으면 에러 발생하므로, 별도의 소유여부확인은 불필요
char = HObject.load("character", params.char_id);
weapon = HObject.load("item", params.weapon_id);

// 장착중이 아니어야 함
if (weapon.equipped == true) {
    return "장착중인 무기";
}

// 이미 장착되어 있으면 해체
if (char.weapon != null) {
    equipped_weapon = HObject.load("item", char.weapon);
    equipped_weapon.equipped = false;
    HObject.save(equipped_weapon);
    char.weapon = null;
}

// 장착
char.weapon = params.weapon_id;
weapon.equipped = true;

HObject.save(char);
HObject.save(weapon);

return {char:char, weapon:weapon};
  • 결과 예:
{
    "result_code": 0,
    "call_return": {
        "char": {
            "class": "character",
            "id": "3391864164588585",
            "index": 1,
            "weapon": "3391871961406505"
        },
        "weapon": {
            "class": "item",
            "id": "3391871961406505",
            "index": 4,
            "equipped": true
        }
    }
}

##buy_character hornet.hive5.io/v5/procedures/call/buy_character?index=4

캐릭터를 구매한다. 구매하려 캐릭터의 index를 넘긴다. 캐릭터의 인덱스와 속성은 charancters 데이터 테이블에 정의되어 있다. 아이템 구매와 달리 캐릭터 구매는 중복이 허용되지 않게 했다.

//params
//index : 구매하려는 캐릭터의 고유번호(character table에 정의)

// index를 갖는 캐릭터 인스턴스를 생성하여, 인벤토리에 저장한다.

var buy_char_index = parseInt(params.index);
var player = HObject.load("player");

var tbl = DataTable.load("character", {index:buy_char_index});
if (tbl.length!=1)
    return "일치조건 없음";

var target = tbl[0];

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

// 이미 구매 했는지 여부확인
for (i=0; i<player.char_inv.length; i++) {
    if (buy_char_index == player.char_inv[i].index) {
        return "already owned";
    }
}

character = HObject.create("character");
character.index = buy_char_index;
HObject.save(character);

player.char_inv.push({id:character.id, index:character.index});
player.coin -= target.price;
HObject.save(player);

return player;
  • 결과 예:
{
    "result_code": 0,
    "call_return": {
        "gold": 10,
        "score": 0,
        "char_inv": [
            {
                "id": "3391864164588585",
                "index": 1
            },
            {
                "id": "3391864167210025",
                "index": 2
            },
            {
                "id": "3391864169897001",
                "index": 3
            },
            {
                "id": "3391887795100713",
                "index": 4
            }
        ],
        "exp": 0,
        "id": null,
        "item_inv": [
            {
                "id": "3391864130968617",
                "index": 1
            },
            {
                "id": "3391864133721129",
                "index": 2
            },
            {
                "id": "3391864136277033",
                "index": 3
            },
            {
                "id": "3391871961406505",
                "index": 4
            }
        ],
        "coin": 89650,
        "class": "player",
        "level": 1
    }
}

##get_heart hornet.hive5.io/v5/procedures/call/get_heart

현재 하트 수를 알려준다. 하트는 시간의 경과에 따라 자동 충전되므로, 다음 충전시간도 알려준다.

function update_heart() {

    // 초기화 안된 경우 추가
    if (player.heart_max==null) {
        player.heart=5;
        player.heart_max=5;
        player.heart_recharging_interval=10*1000; // test로 10초
    }

    // 하트가 최대치이거나, 충전시간에 도달안됐으면 리턴
    if (player.heart_max==player.heart || Date.now()<player.heart_next_recharge) {
        return;
    }

    // 경과 시간으로 충전가능 하트 수 계산
    now = Date.now();
    elapsed_time = now - (player.heart_next_recharge - player.heart_recharging_interval);
    rechargable_heart_count = Math.floor(elapsed_time/player.heart_recharging_interval);

    // 최대치 고려하여 그 수 만큼 충전
    player.heart = player.heart + rechargable_heart_count;
    if (player.heart > player.heart_max)
        player.heart = player.heart_max;

    // 다음 충전시간 갱신
    if (player.heart == player.heart_max)
        player.heart_next_recharge = null;  // 최대치이므로, 다음 충전시간은 없음
    else
        player.heart_next_recharge = now + player.heart_recharging_interval - (elapsed_time % player.heart_recharging_interval);

}


player = HObject.load("player");

update_heart();  //자동충전을 위한 업데이트 함수

HObject.save(player);

return {heart:player.heart, next_recharge:player.heart_next_recharge, now:Date.now()};
  • 결과 예:
{
    "result_code": 0,
    "call_return": {
        "heart": 2,
        "next_recharge": 1400553082996,
        "now": 1400553075876
    }
}

##decrease_heart hornet.hive5.io/v5/procedures/call/decrease_heart

하트를 사용한다. 다음 충전시간을 업데이트하는 로직이 포함되어 있다.

// 하트 감소
player=HObject.load("player");
if (player.heart==0)
    return "사용가능 하트 없음";

player.heart--;

// 다음 충전시간이 null이면 충전가능 시간을 계산해 세팅
if (player.heart_next_recharge==null) {
    player.heart_next_recharge = Date.now() + player.heart_recharging_interval;
}

// save
HObject.save(player);

return {heart:player.heart, next_recharge:player.heart_next_recharge};
  • 결과 예:
{
    "result_code": 0,
    "call_return": {
        "heart": 4,
        "next_recharge": 1400553136623
    }
}

##end_game hornet.hive5.io/v5/procedures/call/end_game?score=200&exp=100

레벨이나, 라운드의 종료와 같이 게임의 점수를 갱신해야 할 필요가 있을 때 사용된다. 예제에서는 점수와 경험치를 합산하며, 경험치가 levelup 데이터 데이블에 정의된 규칙에 따라 어느 이상이 되면, 레벨을 증가시킨다.

//params
//score: 획득한 점수
//exp: 추가로 획득한 경험치

// score는 누적시켜주고, exp는 테이블을 참조하여, 레벨업이 가능하면 레젤업 처리하고, 잔여 exp를 저장한다

player = HObject.load("player");
player.score = player.score + parseInt(params.score);

exp = player.exp + parseInt(params.exp);

//level up 가능확인
tbl = DataTable.load("levelup");

for (i=0; i<tbl.length; i++) {
    if (player.level<tbl[i].level) {
        if (exp >= tbl[i].exp) {
            player.level = tbl[i].level;
            exp = exp - tbl[i].exp;
        }
        else
            break;
    }
}

player.exp = exp;

HObject.save(player);

return player;
  • 결과 예:
{
    "result_code": 0,
    "call_return": {
        "gold": 10,
        "score": 200,
        "char_inv": [
            {
                "id": "3391864164588585",
                "index": 1
            },
            {
                "id": "3391864167210025",
                "index": 2
            },
            {
                "id": "3391864169897001",
                "index": 3
            },
            {
                "id": "3391887795100713",
                "index": 4
            }
        ],
        "exp": 0,
        "heart_next_recharge": 1400553136623,
        "heart_max": 5,
        "id": null,
        "heart_recharging_interval": 10000,
        "item_inv": [
            {
                "id": "3391864130968617",
                "index": 1
            },
            {
                "id": "3391864133721129",
                "index": 2
            },
            {
                "id": "3391864136277033",
                "index": 3
            },
            {
                "id": "3391871961406505",
                "index": 4
            }
        ],
        "coin": 89650,
        "class": "player",
        "heart": 4,
        "level": 2
    }
}

##gacha_item hornet.hive5.io/v5/procedures/call/gacha_item?weapon_type=sword&grade=A

아이템 뽑기를 수행한다. item_gacha 데이터 테이블에 정의된 규칙과 확률에 따라, 비용이 소모되고, 뽑아진 아이템을 추가한다.

//params
//weapon_type : 무기 타입
//grade :  등급

// inner function
function create_new_item(idx) {
    item_inv = HObject.load("item_inv");

    // 아이템 생성하고,
    item = HObject.create("item");
    item.index = idx;
    item.type = "weapon";
    item.equipped = false;

    HObject.save(item);
    
    return item;
}


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

var tbl = DataTable.load("gacha_item", {weapon_type:params.weapon_type, grade:params.grade});
if (tbl.length!=1)
    return "일치조건 없음";

var target = tbl[0];

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

var rnd = Math.floor(Math.random()*100);

if (rnd<target.a_rate)
    new_item_idx = target.a_index;  // a 아이템 결정
else if (rnd<target.a_rate+target.b_rate)
    new_item_idx = target.b_index;  // b 아이템 결정
else
    new_item_idx = target.c_index;  // c 아이템 결정

// 아이템 생성
var item = create_new_item(new_item_idx);

// inventory에 추가
player.item_inv.push({id:item.id, index:item.index});

// 코인 차감
player.coin -= target.coin;
HObject.save(player);

return {player:player, item:item};
  • 결과 예:
{
    "result_code": 0,
    "call_return": {
        "player": {
            "gold": 10,
            "score": 200,
            "char_inv": [
                {
                    "id": "3391864164588585",
                    "index": 1
                },
                {
                    "id": "3391864167210025",
                    "index": 2
                },
                {
                    "id": "3391864169897001",
                    "index": 3
                },
                {
                    "id": "3391887795100713",
                    "index": 4
                }
            ],
            "exp": 0,
            "heart_next_recharge": 1400553136623,
            "heart_max": 5,
            "id": null,
            "heart_recharging_interval": 10000,
            "item_inv": [
                {
                    "id": "3391864130968617",
                    "index": 1
                },
                {
                    "id": "3391864133721129",
                    "index": 2
                },
                {
                    "id": "3391864136277033",
                    "index": 3
                },
                {
                    "id": "3391871961406505",
                    "index": 4
                },
                {
                    "id": "3391976363596841",
                    "index": 2
                }
            ],
            "coin": 89200,
            "class": "player",
            "heart": 4,
            "level": 2
        },
        "item": {
            "equipped": false,
            "id": "3391976363596841",
            "class": "item",
            "type": "weapon",
            "index": 2
        }
    }
}

hash_test

hornet.hive5.io/v5/procedures/call/hash_test?score=30&check=8fd1e73524b35f1432896e3b8e3676ebb8c3942d

프로시져를 호출할 때 DB의 값을 직접 바꿀 수 있는 민감한 데이터의 경우 해킹에 대한 방비가 필요하다. 이를 위해 적절한 규칙에 의해 만들어진 해쉬값을 같이 넘기고, 서버에서는 이를 비교할 수 있다. 아래 예는 점수를 올리는 프로시저인데, 현재 플레이어의 점수, 코인, 그리고 올리려는 점수를 모두 더한 값을 sha1 알고리즘으로 만든 해쉬값을 같이 넘겨 이를 비교하는 부분이 포함되어 있다.

// 넘겨진 params.score를 100%신뢰할 수 없을 때
// 규칙에 의해 만들어진 해쉬값 check도 같이 넘겨서 비교

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

var hash = Security.sha1(player.score+player.coin+parseInt(params.score));

if (params.check != hash)
    return "invalid call"

player.score += parseInt(score);

HObject.save(player);

return player;

challenge_score

challenge_score_10000 미션에 연결되어 있다. 10000점 달성시 미션 완료 API를 호출하면, 이 미션에 연결된 challenge_score 프로시저가 실행된다. 이 프로시저는 미션을 통해서만 실행되므로, protected로 설정해 놓는 것이 좋다. 10000점 이상인 경우 골드를 추가하는 내용이다.

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

if (player.score<10000)
    return "조건불일치"

player.gold += 8000;
HObject.save(player);

return player;

tutorial_complete

tutorial_complete 미션에 연결되어 있다. 튜토리얼을 모두 수행해 미션 완료 API를 호출하면, 이 미션에 연결된 tutorial_complete 프로시저가 실행된다. 이 프로시저는 미션을 통해서만 실행되므로, protected로 설정해 놓는 것이 좋다. 4번 아이템을 받는 내용이다.

//튜토리얼 완료시, 바로 아이템 4를 지급

var item_num = 4;

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

if (tbl.length!=1)
    return "일치조건 없음";
    
var target = tbl[0];

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

player.item_inv.push({id:item.id, index:item.index});
HObject.save(player);

return player;

levelup_mission

levelup_2 미션에 연결되어 있다. 레벨이 2에 도달해 미션 완료 API를 호출하게 되는데, 이 미션은 즉시 수행이 아니다. 이런 경우는 메일함으로 관련 메일이 나가게 되고, 메일함에서 보상받기를 클릭하면 Reward 아이템 사용 API를 호출하는데, 이 때에 미션과 연결된 levelup_mission 프로시저가 수행된다.

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

if (player.level<2)
    return "조건불일치"

player.gold += 500;
HObject.save(player);

return player;

Clone this wiki locally