2050 lines
61 KiB
JavaScript
2050 lines
61 KiB
JavaScript
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Welcome to your first Cloud Script revision!
|
|
//
|
|
// Cloud Script runs in the PlayFab cloud and has full access to the PlayFab Game Server API
|
|
// (https://api.playfab.com/Documentation/Server), and it runs in the context of a securely
|
|
// authenticated player, so you can use it to implement logic for your game that is safe from
|
|
// client-side exploits.
|
|
//
|
|
// Cloud Script functions can also make web requests to external HTTP
|
|
// endpoints, such as a database or private API for your title, which makes them a flexible
|
|
// way to integrate with your existing backend systems.
|
|
//
|
|
// There are several different options for calling Cloud Script functions:
|
|
//
|
|
// 1) Your game client calls them directly using the "ExecuteCloudScript" API,
|
|
// passing in the function name and arguments in the request and receiving the
|
|
// function return result in the response.
|
|
// (https://api.playfab.com/Documentation/Client/method/ExecuteCloudScript)
|
|
//
|
|
// 2) You create PlayStream event actions that call them when a particular
|
|
// event occurs, passing in the event and associated player profile data.
|
|
// (https://api.playfab.com/playstream/docs)
|
|
//
|
|
// 3) For titles using the Photon Add-on (https://playfab.com/marketplace/photon/),
|
|
// Photon room events trigger webhooks which call corresponding Cloud Script functions.
|
|
//
|
|
// The following examples demonstrate all three options.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
handlers.aaTest = function(args)
|
|
{
|
|
//var now = new Date();
|
|
//log.info(now.getFullYear());
|
|
//log.info(now.getMonth());
|
|
//log.info(now.getDate());
|
|
|
|
//var curTime = new Date();
|
|
//var t1 = new Date(curTime.setHours(curTime.getHours() + 1));
|
|
//log.info(t1);
|
|
//var t2 = new Date(t1.setDate(t1.getDate() + 1));
|
|
//log.info(t2);
|
|
|
|
//server.UpdatePlayerStatistics({PlayFabId: currentPlayerId, Statistics : [
|
|
//{
|
|
// "StatisticName": "PetBattle",
|
|
// "Value": 1000
|
|
//}
|
|
//]});
|
|
|
|
/*
|
|
// https://learn.microsoft.com/en-us/rest/api/playfab/server/account-management/get-player-profile?view=playfab-rest#playerprofileviewconstraints
|
|
var playerprofile = server.GetPlayerCombinedInfo({ PlayFabId: currentPlayerId,
|
|
"InfoRequestParameters":
|
|
{
|
|
"GetPlayerProfile": true,
|
|
"ProfileConstraints":
|
|
{
|
|
"ShowTotalValueToDateInUsd": true,
|
|
"ShowDisplayName": true,
|
|
//"ShowStatistics": true, // 순위표 (레거시)
|
|
//"ShowLinkedAccounts": true, // 연결된 계정 (커스텀, 구글, 애플 등)
|
|
}
|
|
}
|
|
});
|
|
log.info(playerprofile);
|
|
if(!CheckNullOrEmpty(playerprofile.InfoResultPayload.PlayerProfile.TotalValueToDateInUSD))
|
|
{
|
|
log.info(playerprofile.InfoResultPayload.PlayerProfile.TotalValueToDateInUSD);
|
|
var price = playerprofile.InfoResultPayload.PlayerProfile.TotalValueToDateInUSD / 100;
|
|
log.info(parseInt(price * 50));
|
|
}
|
|
else
|
|
log.info('no cash buy');
|
|
*/
|
|
|
|
// 타이틀 Id 찾는 법
|
|
// currentPlayerId == master Id
|
|
// playerprofile.TitlePlayerAccounts[currentPlayerId].Id == title Id (★)
|
|
//var playerprofile = entity.GetTitlePlayersFromMasterPlayerAccountIds({ MasterPlayerAccountIds: [currentPlayerId]});
|
|
//var titleId = playerprofile.TitlePlayerAccounts[currentPlayerId].Id;
|
|
//log.info("titleId : " + titleId);
|
|
}
|
|
|
|
// 에러 정리 : 0 정상, 1 채팅 금지 유저, 2 서버 점검, 3 잘못된 우편을
|
|
// -1 중복 로그인, -2 금지 유저
|
|
function Get_Error(readonlydata, token)
|
|
{
|
|
const PassIDs = [ "20037ADFE4BC365B", "24595CBA317234B8" ];
|
|
if (PassIDs.includes(currentPlayerId))
|
|
{
|
|
log.info("Pass by PassIDs.");
|
|
return 0; // 지정된 아이디면 그냥 통과
|
|
}
|
|
|
|
if (readonlydata.Data.CurToken.Value != token)
|
|
return -1;
|
|
/*
|
|
else if (!CheckNullOrEmpty(uidata.BanUser))
|
|
return -2;
|
|
else if (!CheckNullOrEmpty(uidata.BanChat))
|
|
return 1;
|
|
*/
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
handlers.Send_Mail = function(args)
|
|
{
|
|
Add_Mail(args);
|
|
}
|
|
|
|
function Add_Mail(args)
|
|
{
|
|
var makemail = {};
|
|
makemail.ItemID = args.ItemID;
|
|
makemail.Amount = args.Amount;
|
|
makemail.Msg = args.Msg;
|
|
|
|
var day = CheckNullOrEmpty(args.Day) ? 3 : args.Day;
|
|
var dt = Get_CurKoreaTime();
|
|
makemail.RemainTime = new Date(dt.setDate(dt.getDate() + day));
|
|
|
|
var readonlydata = Get_UserReadOnlyData();
|
|
var mailjson = [];
|
|
if (!CheckNullOrEmpty(readonlydata.Data.Mail))
|
|
mailjson = JSON.parse(readonlydata.Data.Mail.Value);
|
|
mailjson.push(makemail);
|
|
|
|
// 시간 지난 메일 확인 후 삭제
|
|
for(var i in mailjson)
|
|
{
|
|
var mailtime = new Date(mailjson[i].RemainTime);
|
|
var nowtime = Get_CurKoreaTime();
|
|
if(mailtime - nowtime < 0)
|
|
delete mailjson[i];
|
|
}
|
|
mailjson = mailjson.filter(function(x) { return x !== null }); // null 모두 지우기
|
|
|
|
Set_MailData(mailjson);
|
|
|
|
return {
|
|
result : mailjson
|
|
};
|
|
}
|
|
|
|
handlers.Get_UserInfo = function (args)
|
|
{
|
|
var readonlydata = Get_UserReadOnlyData();
|
|
return Get_Return(Get_Error(readonlydata, args.Token), { GetUserReadOnlyData: readonlydata.Data });
|
|
}
|
|
handlers.Get_OtherUserInfo = function (args)
|
|
{
|
|
var urod = server.GetUserReadOnlyData({ PlayFabId: args.ID }).Data;
|
|
|
|
return {
|
|
error: Get_Error(args.Token),
|
|
GetUserReadOnlyData: urod
|
|
};
|
|
}
|
|
|
|
handlers.ServerSave_LoginToken = function(args)
|
|
{
|
|
server.UpdateUserReadOnlyData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"CurToken": args.Token} });
|
|
//server.UpdateUserInternalData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"CurToken": args.Token } });
|
|
}
|
|
|
|
handlers.ServerSave_AllData = function(args)
|
|
{
|
|
var error = Get_Error(Get_UserReadOnlyData(), args.Token);
|
|
if (error < 0) return Get_Return(error);
|
|
|
|
server.UpdateUserReadOnlyData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"UserInfo": JSON.stringify(args.AllData)} });
|
|
|
|
return Get_Return(error);
|
|
}
|
|
|
|
/////////////////////////////////// 서버 처리
|
|
// table 변수는 기본적으로 미션 테이블
|
|
function Get_UserReadOnlyData()
|
|
{
|
|
return server.GetUserReadOnlyData({ PlayFabId: currentPlayerId });
|
|
}
|
|
function Get_JsonUserData(readonlydata)
|
|
{
|
|
return JSON.parse(readonlydata.Data.UserInfo.Value);
|
|
}
|
|
function Set_JsonUserData(urod)
|
|
{
|
|
urod.LastTime = Get_CurKoreaTime();
|
|
server.UpdateUserReadOnlyData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"UserInfo": JSON.stringify(urod)} });
|
|
}
|
|
function Set_MailData(mailjson)
|
|
{
|
|
server.UpdateUserReadOnlyData({ PlayFabId: currentPlayerId, Data: {"Mail": JSON.stringify(mailjson)} });
|
|
}
|
|
function Get_Return(errorval, add) {
|
|
var rtn = {
|
|
error: errorval,
|
|
time: Get_CurKoreaTime()
|
|
};
|
|
|
|
if (add && typeof add === 'object' && !Array.isArray(add)) {
|
|
for (var key in add) {
|
|
if (add.hasOwnProperty(key)) {
|
|
rtn[key] = add[key];
|
|
}
|
|
}
|
|
}
|
|
|
|
//log.info(rtn.error + ", " + rtn.time);
|
|
return rtn;
|
|
|
|
/*
|
|
var result = Get_Return(0, { gold: 1000, name: "player1" });
|
|
|
|
결과:
|
|
{
|
|
error: 0,
|
|
time: "2025-06-16T10:30:00.000Z", // 예시
|
|
gold: 1000,
|
|
name: "player1"
|
|
}
|
|
*/
|
|
}
|
|
function Add_Item(table, itemtable, urod, itemid, amount, isCheat)
|
|
{
|
|
var itemdata = itemtable.find(f => f.n_ItemID == itemid);
|
|
if (!itemdata) {
|
|
log.error("Add_Item - Invalid item ID: " + itemid);
|
|
return;
|
|
}
|
|
|
|
Add_MissionCount(table, urod, "TAKE_GOODS", itemid, amount, false);
|
|
Add_MissionCount(table, urod, "TAKE_GOODS_LIMIT", itemid, amount, false);
|
|
Add_MissionCount(table, urod, "TAKE_GOODS_ACC", itemid, amount, false);
|
|
|
|
switch (itemdata.e_ItemType)
|
|
{
|
|
default:
|
|
if (!urod.Item[itemid]) urod.Item[itemid] = [0, 0, 0];
|
|
urod.Item[itemid][0] += amount;
|
|
if (!isCheat) urod.Item[itemid][1] += amount; // 총 획득량
|
|
break;
|
|
|
|
case "Weapon":
|
|
case "Armor":
|
|
case "Helmet":
|
|
case "Extra":
|
|
case "Necklace":
|
|
case "Ring":
|
|
if (!urod.Equipment[itemid]) urod.Equipment[itemid] = [0, 0, 0];
|
|
urod.Equipment[itemid][0] += amount;
|
|
Add_Collection(urod, itemid, amount);
|
|
break;
|
|
|
|
case "Skill":
|
|
if (!urod.Skill[itemid]) urod.Skill[itemid] = [amount - 1,1,0]; // 레벨 증가
|
|
else urod.Skill[itemid][0] += amount;
|
|
break;
|
|
|
|
case "PC":
|
|
if (!urod.PC.Obtain.includes(itemid))
|
|
urod.PC.Obtain.push(itemid);
|
|
break;
|
|
|
|
case "Pet":
|
|
if (!urod.Pet[itemid]) urod.Pet[itemid] = [0, 1]; // [레벨, 획득 수]
|
|
urod.Pet[itemid][0] += amount;
|
|
break;
|
|
|
|
case "Enchant":
|
|
if (!urod.Enchant[itemid]) urod.Enchant[itemid] = [0, 0, 0, 0];
|
|
urod.Enchant[itemid][0] += amount;
|
|
urod.Enchant[itemid][2] += amount;
|
|
break;
|
|
|
|
case "Relic":
|
|
if (!urod.Relic[itemid]) urod.Relic[itemid] = [0, 0, 0];
|
|
urod.Relic[itemid][0] += amount;
|
|
break;
|
|
}
|
|
}
|
|
function Use_Item(table, urod, itemid, amount)
|
|
{
|
|
Add_MissionCount(table, urod, "CONSUME_GOODS", itemid, amount, false);
|
|
Add_MissionCount(table, urod, "CONSUME_GOODS_ACC", itemid, amount, false);
|
|
|
|
if (urod.Item[itemid])
|
|
{
|
|
if (urod.Item[itemid][0] >= amount)
|
|
{
|
|
urod.Item[itemid][0] -= amount;
|
|
urod.Item[itemid][2] += amount; // 총 사용량
|
|
return true;
|
|
}
|
|
}
|
|
else if (urod.Equipment[itemid])
|
|
{
|
|
if (urod.Equipment[itemid][0] >= amount)
|
|
{
|
|
urod.Equipment[itemid][0] -= amount;
|
|
return true;
|
|
}
|
|
}
|
|
else if (urod.Skill[itemid])
|
|
{
|
|
if (urod.Skill[itemid][0] >= amount)
|
|
{
|
|
urod.Skill[itemid][0] -= amount;
|
|
return true;
|
|
}
|
|
}
|
|
else if (urod.Pet[itemid])
|
|
{
|
|
if (urod.Pet[itemid][0] >= amount)
|
|
{
|
|
urod.Pet[itemid][0] -= amount;
|
|
return true;
|
|
}
|
|
}
|
|
else if (urod.Enchant[itemid])
|
|
{
|
|
if (urod.Enchant[itemid][0] >= amount)
|
|
{
|
|
urod.Enchant[itemid][0] -= amount;
|
|
urod.Enchant[itemid][3] += amount;
|
|
return true;
|
|
}
|
|
}
|
|
else if (urod.Relic[itemid])
|
|
{
|
|
if (urod.Relic[itemid][0] >= amount)
|
|
{
|
|
urod.Relic[itemid][0] -= amount;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function Add_MissionCount(table, urod, purpose, conditionvalue, count, setValue) {
|
|
if (count <= 0) return;
|
|
|
|
//var table = Get_MissionTable(); // 전체 미션 테이블을 외부에서 받는 걸로 변경 (1번만 호출하기 위함)
|
|
var matchingMissions = [];
|
|
|
|
// 조건에 맞는 미션만 추림
|
|
for (var i = 0; i < table.length; i++) {
|
|
if (table[i].e_MissionConditionType == purpose)
|
|
{
|
|
matchingMissions.push(table[i]);
|
|
//log.info(purpose + " : " + table[i].e_MissionConditionType + ", " + table[i].n_MissionGroupId + ", " + table[i].n_MissionIndex);
|
|
}
|
|
}
|
|
|
|
// 조건에 맞는 미션들만 처리
|
|
for (var i = 0; i < matchingMissions.length; i++) {
|
|
var mission = matchingMissions[i];
|
|
|
|
// 조건 값 확인
|
|
//log.info("typeof n_MissionConditionValue: " + typeof mission.n_MissionConditionValue);
|
|
//log.info("typeof conditionvalue: " + typeof conditionvalue);
|
|
//log.info("n_MissionConditionValue: " + mission.n_MissionConditionValue);
|
|
//log.info("conditionvalue: " + conditionvalue);
|
|
if (mission.n_MissionConditionValue == 0 || conditionvalue == mission.n_MissionConditionValue) {
|
|
var key1 = mission.n_MissionGroupId;
|
|
var key2 = mission.n_MissionIndex;
|
|
|
|
if (!urod.Mission[key1]) urod.Mission[key1] = {};
|
|
if (!urod.Mission[key1][key2]) urod.Mission[key1][key2] = [0, 0];
|
|
|
|
if (setValue) urod.Mission[key1][key2][1] = count;
|
|
else urod.Mission[key1][key2][1] += count;
|
|
}
|
|
}
|
|
|
|
// 가이드 퀘스트 체크
|
|
var guideData = table.find(f=>f.n_MissionGroupId == 0 && f.n_MissionIndex == urod.Common[10]);
|
|
if (guideData && guideData.e_MissionConditionType == purpose)
|
|
urod.Common[11] += count;
|
|
}
|
|
function Add_Collection(urod, id, count)
|
|
{
|
|
if (!urod.Collection[id]) urod.Collection[id] = 0;
|
|
urod.Collection[id] += count;
|
|
}
|
|
function Add_MobCollection(urod, id, count)
|
|
{
|
|
if (!urod.MobKill[id]) urod.MobKill[id] = 0;
|
|
urod.MobKill[id] += count;
|
|
}
|
|
|
|
function Get_Exp(lv) {
|
|
var base = (lv * 10) + 21 + (lv * 50);
|
|
var exp = Math.pow(base, 1.05 + Math.sqrt(lv * 0.0000000001));
|
|
return Math.max(Math.floor(exp), 0);
|
|
}
|
|
|
|
handlers.Save_CheatItem = function(args)
|
|
{
|
|
var urod = Get_JsonUserData(Get_UserReadOnlyData());
|
|
Add_Item(Get_MissionTable(), Get_ItemTable(), urod, args.ID, args.Amount, true);
|
|
Set_JsonUserData(urod);
|
|
}
|
|
|
|
handlers.Get_MailList = function(args)
|
|
{
|
|
var readonlydata = Get_UserReadOnlyData();
|
|
var mailList = [];
|
|
|
|
if (readonlydata.Data.Mail && readonlydata.Data.Mail.Value)
|
|
{
|
|
try {
|
|
mailList = JSON.parse(readonlydata.Data.Mail.Value);
|
|
} catch (e) {
|
|
log.error("Mail JSON Parse Error: " + e);
|
|
mailList = []; // 파싱 실패시 빈 목록 반환
|
|
}
|
|
}
|
|
|
|
return Get_Return(Get_Error(readonlydata, args.Token), { Mail: mailList });
|
|
}
|
|
handlers.Get_MailReward = function(args)
|
|
{
|
|
var readonlydata = Get_UserReadOnlyData();
|
|
var error = Get_Error(readonlydata, args.Token);
|
|
if (error < 0) return Get_Return(error);
|
|
|
|
if (!CheckNullOrEmpty(readonlydata.Data.Mail))
|
|
{
|
|
var table = Get_MissionTable();
|
|
var itemtable = Get_ItemTable();
|
|
var urod = Get_JsonUserData(readonlydata);
|
|
var mailjson = JSON.parse(readonlydata.Data.Mail.Value);
|
|
var existmail = false;
|
|
var getdate = new Date(args.RemainTime);
|
|
for (var i in mailjson)
|
|
{
|
|
var maildate = new Date(mailjson[i].RemainTime);
|
|
if (maildate.getTime() === getdate.getTime())
|
|
{
|
|
existmail = true;
|
|
Add_Item(table, itemtable, urod, mailjson[i].ItemID, mailjson[i].Amount);
|
|
delete mailjson[i];
|
|
break;
|
|
}
|
|
}
|
|
mailjson = mailjson.filter(function(x) { return x !== null }); // null 모두 지우기
|
|
|
|
if (existmail)
|
|
{
|
|
Set_MailData(mailjson);
|
|
Set_JsonUserData(urod);
|
|
return Get_Return(error, { Mail: mailjson } );
|
|
}
|
|
else
|
|
return Get_Return(3);
|
|
}
|
|
else
|
|
return Get_Return(3);
|
|
}
|
|
handlers.Get_AllMail = function(args)
|
|
{
|
|
var readonlydata = Get_UserReadOnlyData();
|
|
var error = Get_Error(readonlydata, args.Token);
|
|
if (error < 0) return Get_Return(error);
|
|
|
|
if (!CheckNullOrEmpty(readonlydata.Data.Mail))
|
|
{
|
|
var table = Get_MissionTable();
|
|
var itemtable = Get_ItemTable();
|
|
var urod = Get_JsonUserData(readonlydata);
|
|
var mailjson = JSON.parse(readonlydata.Data.Mail.Value);
|
|
for (var i in mailjson)
|
|
Add_Item(table, itemtable, urod, mailjson[i].ItemID, mailjson[i].Amount);
|
|
|
|
Set_MailData([]);
|
|
Set_JsonUserData(urod);
|
|
|
|
return Get_Return(error, { Mail: mailjson });
|
|
}
|
|
else
|
|
return Get_Return(3);
|
|
}
|
|
|
|
handlers.Save_StageResult = function(args) {
|
|
var readonlydata = Get_UserReadOnlyData();
|
|
var error = Get_Error(readonlydata, args.Token);
|
|
if (error < 0) return Get_Return(error);
|
|
|
|
var urod = Get_JsonUserData(readonlydata);
|
|
var table = Get_MissionTable();
|
|
var itemtable = Get_ItemTable();
|
|
|
|
// 경험치 처리
|
|
urod.PC.Exp += args.Exp;
|
|
while (urod.PC.Exp >= Get_Exp(urod.PC.Lv + 1)) {
|
|
urod.PC.Lv++;
|
|
}
|
|
|
|
// 아이템 처리 (args.Item은 JS object 형태로 전달됨)
|
|
var items = args.Item; // ex: { "1001": 3, "1002": 1 }
|
|
for (var key in items) {
|
|
var itemId = key;
|
|
var itemCount = items[key];
|
|
|
|
Add_Item(table, itemtable, urod, itemId, itemCount);
|
|
}
|
|
|
|
// 몬스터 킬 처리
|
|
var mobcount = 0;
|
|
for (var key in args.Mob) {
|
|
var Id = key;
|
|
var Count = args.Mob[key];
|
|
mobcount += Count;
|
|
Add_MissionCount(table, urod, "KILL_MONSTER", Id, Count, false);
|
|
Add_MobCollection(urod, Id, Count);
|
|
}
|
|
var elitemobcount = 0;
|
|
for (var key in args.Elite) {
|
|
var Id = key;
|
|
var Count = args.Elite[key];
|
|
elitemobcount += Count;
|
|
Add_MissionCount(table, urod, "KILL_MONSTER", Id, Count, false);
|
|
Add_MobCollection(urod, Id, Count);
|
|
}
|
|
var bossmobcount = 0;
|
|
for (var key in args.Boss) {
|
|
var Id = key;
|
|
var Count = args.Boss[key];
|
|
bossmobcount += Count;
|
|
Add_MissionCount(table, urod, "KILL_MONSTER", Id, Count, false);
|
|
Add_MobCollection(urod, Id, Count);
|
|
}
|
|
|
|
Add_MissionCount(table, urod, "KILL_MONSTER_ALL", 0, mobcount + elitemobcount + bossmobcount, false);
|
|
Add_MissionCount(table, urod, "KILL_MONSTER_ACC", 0, mobcount + elitemobcount + bossmobcount, false);
|
|
Add_MissionCount(table, urod, "KILL_MONSTER_GRADE", 1, mobcount, false);
|
|
Add_MissionCount(table, urod, "KILL_MONSTER_GRADE", 2, elitemobcount, false);
|
|
Add_MissionCount(table, urod, "KILL_MONSTER_GRADE", 3, bossmobcount, false);
|
|
Add_MissionCount(table, urod, "KILL_MONSTER_GRADE_ACC", 1, mobcount, false);
|
|
Add_MissionCount(table, urod, "KILL_MONSTER_GRADE_ACC", 2, elitemobcount, false);
|
|
Add_MissionCount(table, urod, "KILL_MONSTER_GRADE_ACC", 3, bossmobcount, false);
|
|
|
|
Set_JsonUserData(urod);
|
|
return Get_Return(0);
|
|
}
|
|
|
|
handlers.Save_PC_Stat = function(args)
|
|
{
|
|
var readonlydata = Get_UserReadOnlyData();
|
|
var error = Get_Error(readonlydata, args.Token);
|
|
if (error < 0) return Get_Return(error);
|
|
|
|
if (!args.UsePoint || args.UsePoint.length !== 4) {
|
|
return Get_Return(2); // invalid input
|
|
}
|
|
|
|
for (var i = 0; i < 4; i++) {
|
|
if (args.UsePoint[i] < 0)
|
|
return Get_Return(3); // no negative values allowed
|
|
}
|
|
|
|
var urod = Get_JsonUserData(readonlydata);
|
|
var usedPoint = urod.PC.Stat.reduce((a, b) => a + b, 0);
|
|
var totalPoint = (urod.PC.Lv - 1) * 5;
|
|
var remainPoint = totalPoint - usedPoint;
|
|
|
|
var curUsePoint = args.UsePoint.reduce((a, b) => a + b, 0);
|
|
|
|
if (curUsePoint <= remainPoint) {
|
|
for (var i = 0; i < 4; i++) {
|
|
urod.PC.Stat[i] += args.UsePoint[i];
|
|
}
|
|
Add_MissionCount(Get_MissionTable(), urod, "HERO_STAT_UPGRADE_ACC", 0, curUsePoint, false);
|
|
Set_JsonUserData(urod);
|
|
return Get_Return(0);
|
|
} else {
|
|
return Get_Return(1); // not enough points
|
|
}
|
|
}
|
|
handlers.Save_PC_StatInit = function(args)
|
|
{
|
|
var readonlydata = Get_UserReadOnlyData();
|
|
var error = Get_Error(readonlydata, args.Token);
|
|
if (error < 0) return Get_Return(error);
|
|
|
|
var urod = Get_JsonUserData(readonlydata);
|
|
var rtnerror = 2; // 실패 (재화 부족)
|
|
var useGem = 100;
|
|
if (urod.Common[8] == 0)
|
|
{ // 최초 무료
|
|
urod.Common[8] = 1;
|
|
rtnerror = 1;
|
|
useGem = 0;
|
|
}
|
|
else
|
|
{
|
|
if (Use_Item(Get_MissionTable(), urod, 1, useGem))
|
|
rtnerror = 0;
|
|
}
|
|
|
|
if (rtnerror >= 0 && rtnerror < 2)
|
|
{
|
|
for (var i = 0; i < 4; i++)
|
|
urod.PC.Stat[i] = 0;
|
|
Set_JsonUserData(urod);
|
|
}
|
|
|
|
return Get_Return(rtnerror, { gem: useGem });
|
|
}
|
|
|
|
handlers.Save_PC_Ability = function(args)
|
|
{
|
|
var readonlydata = Get_UserReadOnlyData();
|
|
var error = Get_Error(readonlydata, args.Token);
|
|
if (error < 0) return Get_Return(error);
|
|
|
|
var table = Get_AbilityConfigTable();
|
|
var data = table.find(f => f.n_AbilityID == args.AbilityID);
|
|
if (!data) return Get_Return(3); // 잘못된 특성 ID
|
|
|
|
var urod = Get_JsonUserData(readonlydata);
|
|
|
|
if (data.n_MaxUpgradeLevel <= (urod.Ability[args.AbilityID] || 0))
|
|
return Get_Return(1); // 이미 최대 레벨
|
|
|
|
// 특성 선행 조건 체크
|
|
if (data.n_RequireAbility1 > 0)
|
|
{
|
|
var requireData = table.find(f => f.n_AbilityID == data.n_RequireAbility1);
|
|
if (!urod.Ability[data.n_RequireAbility1] || urod.Ability[data.n_RequireAbility1] < requireData.n_MaxUpgradeLevel)
|
|
return Get_Return(5); // 선행 특성이 최고 레벨이 아님
|
|
}
|
|
if (data.n_RequireAbility2 > 0)
|
|
{
|
|
var requireData = table.find(f => f.n_AbilityID == data.n_RequireAbility2);
|
|
if (!urod.Ability[data.n_RequireAbility2] || urod.Ability[data.n_RequireAbility2] < requireData.n_MaxUpgradeLevel)
|
|
return Get_Return(5); // 선행 특성이 최고 레벨이 아님
|
|
}
|
|
|
|
var global = Get_GlobalValueTable();
|
|
var matdata = global.find(f => f.s_ID == "n_AbilityMaterialID");
|
|
if (!matdata) return Get_Return(4); // 설정 누락
|
|
|
|
var table = Get_MissionTable();
|
|
var materialId = matdata.n_Value;
|
|
if (Use_Item(table, urod, materialId, 1))
|
|
{
|
|
// 특성 레벨업
|
|
if (!urod.Ability[args.AbilityID])
|
|
urod.Ability[args.AbilityID] = 0;
|
|
++urod.Ability[args.AbilityID];
|
|
|
|
// 미션 카운트
|
|
Add_MissionCount(table, urod, "HERO_ABILITY_UPGRADE_CLASS_LIMIT", args.nBattleType, 1, false);
|
|
Add_MissionCount(table, urod, "HERO_ABILITY_UPGRADE_ALL", 0, 1, false);
|
|
Add_MissionCount(table, urod, "HERO_ABILITY_UPGRADE_ACC", 0, 1, false);
|
|
|
|
Set_JsonUserData(urod);
|
|
return Get_Return(0);
|
|
}
|
|
else
|
|
return Get_Return(2); // 재료 없음
|
|
}
|
|
handlers.Save_PC_AbilityInit = function(args)
|
|
{
|
|
var readonlydata = Get_UserReadOnlyData();
|
|
var error = Get_Error(readonlydata, args.Token);
|
|
if (error < 0) return Get_Return(error);
|
|
|
|
var urod = Get_JsonUserData(readonlydata);
|
|
var Gem = 100;
|
|
|
|
var itemtable = Get_ItemTable();
|
|
var table = Get_MissionTable();
|
|
var abilitytable = Get_AbilityConfigTable();
|
|
var global = Get_GlobalValueTable();
|
|
|
|
if (Use_Item(itemtable, urod, 1, Gem))
|
|
{
|
|
var matdata = global.find(f => f.s_ID == "n_AbilityMaterialID");
|
|
if (!matdata) return Get_Return(1); // 설정 누락
|
|
var materialId = matdata.n_Value;
|
|
|
|
// 특성 초기화 및 재료 환급
|
|
var lst = abilitytable.filter(f => f.e_BattleType == args.BattleType);
|
|
for (var i = 0; i < lst.length; ++i)
|
|
{
|
|
var key = lst[i].n_AbilityID;
|
|
if (urod.Ability[key])
|
|
{
|
|
Add_Item(table, itemtable, urod, materialId, urod.Ability[key]);
|
|
urod.Ability[key] = 0;
|
|
}
|
|
}
|
|
|
|
// 미션 카운트
|
|
Add_MissionCount(table, urod, "HERO_ABILITY_RESET_ACC", 0, 1, false);
|
|
|
|
Set_JsonUserData(urod);
|
|
return Get_Return(0, { gem: Gem });
|
|
}
|
|
else
|
|
{
|
|
return Get_Return(2); // 젬 부족
|
|
}
|
|
}
|
|
|
|
handlers.Save_PC_BuyJob = function(args)
|
|
{
|
|
var readonlydata = Get_UserReadOnlyData();
|
|
var error = Get_Error(readonlydata, args.Token);
|
|
if (error < 0) return Get_Return(error);
|
|
|
|
var urod = Get_JsonUserData(readonlydata);
|
|
|
|
var global = Get_GlobalValueTable();
|
|
var matdata = global.find(f => f.s_ID == "n_JobMaterialID");
|
|
if (!matdata) return Get_Return(1); // 설정 누락
|
|
var materialId = matdata.n_Value;
|
|
|
|
if (urod.PC.Obtain.includes(args.JobID))
|
|
return Get_Return(3); // 가진 직업
|
|
|
|
var classopentable = Get_ClassOpenTable();
|
|
var m_Data = classopentable.find(f=>f.n_ClassID == args.JobID);
|
|
// linkedId1 확인
|
|
const linkedClass1 = parseInt(m_Data.n_linkedClass1);
|
|
if (linkedClass1 > 0 && !urod.PC.Obtain.map(id => parseInt(id)).includes(linkedClass1))
|
|
return Get_Return(4);
|
|
|
|
// linkedId2 확인
|
|
const linkedClass2 = parseInt(m_Data.n_linkedClass2);
|
|
if (linkedClass2 > 0 && !urod.PC.Obtain.map(id => parseInt(id)).includes(linkedClass2))
|
|
return Get_Return(4);
|
|
|
|
// 특성 확인
|
|
if (m_Data.n_RequireAbility > 0)
|
|
{
|
|
if (!urod.Ability[m_Data.n_RequireAbility] || urod.Ability[m_Data.n_RequireAbility] < 1)
|
|
return Get_Return(5);
|
|
}
|
|
|
|
// 각성 확인 1
|
|
if (m_Data.e_RequireAwakenType1 != "None")
|
|
{
|
|
if (!urod.Awaken[m_Data.e_RequireAwakenType1] || urod.Awaken[m_Data.e_RequireAwakenType1].Lv < m_Data.n_RequireAwakenStep1)
|
|
return Get_Return(6);
|
|
}
|
|
|
|
// 각성 확인 2
|
|
if (m_Data.e_RequireAwakenType2 != "None")
|
|
{
|
|
if (!urod.Awaken[m_Data.e_RequireAwakenType2] || urod.Awaken[m_Data.e_RequireAwakenType2].Lv < m_Data.n_RequireAwakenStep2)
|
|
return Get_Return(6);
|
|
}
|
|
|
|
var itemtable = Get_ItemTable();
|
|
if (Use_Item(itemtable, urod, matdata.n_Value, m_Data.n_NeedGoodsCount))
|
|
{
|
|
var table = Get_MissionTable();
|
|
Add_Item(table, itemtable, urod, args.JobID, 1);
|
|
|
|
Set_JsonUserData(urod);
|
|
return Get_Return(0);
|
|
}
|
|
else
|
|
{
|
|
return Get_Return(2); // 재화 부족
|
|
}
|
|
}
|
|
handlers.Save_PC_EquipJob = function(args)
|
|
{
|
|
var readonlydata = Get_UserReadOnlyData();
|
|
var error = Get_Error(readonlydata, args.Token);
|
|
if (error < 0) return Get_Return(error);
|
|
|
|
var urod = Get_JsonUserData(readonlydata);
|
|
|
|
if (!urod.PC.Obtain.includes(args.JobID))
|
|
return Get_Return(1); // 없는 직업
|
|
|
|
urod.Equip.Equip["PC"] = args.JobID;
|
|
|
|
Set_JsonUserData(urod);
|
|
return Get_Return(0);
|
|
}
|
|
handlers.Save_PC_AwakenLvUp = function(args)
|
|
{
|
|
var readonlydata = Get_UserReadOnlyData();
|
|
var error = Get_Error(readonlydata, args.Token);
|
|
if (error < 0) return Get_Return(error);
|
|
|
|
var urod = Get_JsonUserData(readonlydata);
|
|
|
|
var global = Get_GlobalValueTable();
|
|
var matdata = global.find(f => f.s_ID == "AWAKEN_GOODS_UPGRADE");
|
|
if (!matdata) return Get_Return(1); // 설정 누락
|
|
var materialId = matdata.n_Value;
|
|
|
|
var awakenupgradetable = [
|
|
{
|
|
"n_AwakenStep": "1",
|
|
"n_MaxUpgradeLevel": "10",
|
|
"n_AwakenGoodsCost": "1",
|
|
"n_DefaultUpgradeCostValue": "3",
|
|
"f_CountPerUpgradeCostValue": "1.5",
|
|
"f_BalanceConstant": "0.032"
|
|
},
|
|
{
|
|
"n_AwakenStep": "2",
|
|
"n_MaxUpgradeLevel": "25",
|
|
"n_AwakenGoodsCost": "2",
|
|
"n_DefaultUpgradeCostValue": "4",
|
|
"f_CountPerUpgradeCostValue": "1.5",
|
|
"f_BalanceConstant": "0.032"
|
|
},
|
|
{
|
|
"n_AwakenStep": "3",
|
|
"n_MaxUpgradeLevel": "30",
|
|
"n_AwakenGoodsCost": "3",
|
|
"n_DefaultUpgradeCostValue": "5",
|
|
"f_CountPerUpgradeCostValue": "1.5",
|
|
"f_BalanceConstant": "0.032"
|
|
}
|
|
];
|
|
|
|
Set_JsonUserData(urod);
|
|
return Get_Return(0);
|
|
}
|
|
/////////////////////////////////// 서버 처리
|
|
|
|
handlers.Write_UnityInApp = function(args)
|
|
{
|
|
server.UpdateUserReadOnlyData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"UserInfo": JSON.stringify(args.AllData)} });
|
|
Add_ShopMail(args.ProductID);
|
|
|
|
log.info("args.IsEditor " + args.IsEditor);
|
|
if (args.IsEditor)
|
|
{
|
|
log.info("아이템 저장 " + args.ProductID);
|
|
server.GrantItemsToUser( { PlayFabID: currentPlayerId, ItemIds : [args.ProductID] });
|
|
}
|
|
|
|
return {
|
|
error: Get_Error(args.Token)
|
|
}
|
|
}
|
|
handlers.Write_Onestore = function(args)
|
|
{
|
|
server.UpdateUserReadOnlyData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"UserInfo": JSON.stringify(args.AllData)} });
|
|
Add_ShopMail(args.ProductID);
|
|
|
|
var customData = { };
|
|
customData["Receipt"] = args.Receipt;
|
|
|
|
server.GrantItemsToUsers({
|
|
"ItemGrants": [{
|
|
"PlayFabId" : currentPlayerId,
|
|
"ItemId" : args.ProductID,
|
|
"Data" : customData
|
|
}]
|
|
});
|
|
|
|
return {
|
|
error: Get_Error(args.Token)
|
|
}
|
|
}
|
|
|
|
function Add_ShopMail(productid)
|
|
{
|
|
var shoptable = Get_ShopTable();
|
|
var finddata = shoptable.find(f=>f.s_InappID == productid);
|
|
if(!CheckNullOrEmpty(finddata))
|
|
{
|
|
var maildata = {};
|
|
maildata.Day = 30;
|
|
maildata.ItemID = finddata.n_ShopItemID;
|
|
maildata.Amount = 1;
|
|
Add_Mail(maildata);
|
|
}
|
|
}
|
|
|
|
handlers.SendMail_Daily = function(args)
|
|
{
|
|
var error = Get_Error(args.Token);
|
|
if(error < 0) return {error:error};
|
|
|
|
server.UpdateUserReadOnlyData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"UserInfo": JSON.stringify(args.AllData)} });
|
|
if(args.IsKing)
|
|
Add_ShopMail("com.filgoodbandits.john.dailyking");
|
|
if(args.IsGod)
|
|
Add_ShopMail("com.filgoodbandits.john.dailygod");
|
|
if(args.IsGemSubscribe)
|
|
{
|
|
var maildata = {};
|
|
maildata.Day = 30;
|
|
maildata.Reward = "GemSubscribeBox1";
|
|
maildata.RewardAmount = 1;
|
|
maildata.Msg = "그리폰이 배달한 주머니입니다.";
|
|
Add_Mail(maildata);
|
|
}
|
|
if(args.IsGemSubscribe2)
|
|
{
|
|
var maildata = {};
|
|
maildata.Day = 30;
|
|
maildata.Reward = "GemSubscribeBox2";
|
|
maildata.RewardAmount = 1;
|
|
maildata.Msg = "흰토끼가 배달한 주머니입니다.";
|
|
Add_Mail(maildata);
|
|
}
|
|
if(args.IsGemSubscribe3)
|
|
{
|
|
var maildata = {};
|
|
maildata.Day = 30;
|
|
maildata.Reward = "GemSubscribeBox3";
|
|
maildata.RewardAmount = 1;
|
|
maildata.Msg = "모조 거북이 배달한 주머니입니다.";
|
|
Add_Mail(maildata);
|
|
}
|
|
|
|
return {
|
|
error: error
|
|
}
|
|
}
|
|
handlers.GuideQuestComplete = function(args)
|
|
{
|
|
var error = Get_Error(args.Token);
|
|
if(error < 0) return {error:error};
|
|
|
|
server.UpdateUserReadOnlyData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"UserInfo": JSON.stringify(args.AllData)} });
|
|
|
|
var maildata = {};
|
|
maildata.Reward = "Gem";
|
|
maildata.RewardAmount = 1000;
|
|
maildata.Msg = "가이드 퀘스트 완료를 축하합니다.";
|
|
Add_Mail(maildata);
|
|
|
|
return {
|
|
error: error
|
|
}
|
|
}
|
|
|
|
handlers.Save_Rank = function(args)
|
|
{
|
|
progression.UpdateLeaderboardEntries({PlayFabId: currentPlayerId, LeaderboardName: args.LeaderboardName,
|
|
Entries :
|
|
[
|
|
{
|
|
"EntityId": args.EntityID,
|
|
"Metadata": args.Metadata,
|
|
"Scores": args.Scores
|
|
}
|
|
]});
|
|
}
|
|
|
|
handlers.SaveToStageRank = function(args)
|
|
{
|
|
var error = Get_Error(args.Token);
|
|
if(error < 0) return {error:error};
|
|
|
|
server.UpdatePlayerStatistics({PlayFabId: currentPlayerId, Statistics : [
|
|
{
|
|
"StatisticName": "Stage",
|
|
"Value": args.MaxStage
|
|
}
|
|
]});
|
|
|
|
return {
|
|
error: error
|
|
}
|
|
}
|
|
handlers.SaveToDragonRank = function(args)
|
|
{
|
|
var error = Get_Error(args.Token);
|
|
if(error < 0) return {error:error};
|
|
|
|
server.UpdatePlayerStatistics({PlayFabId: currentPlayerId, Statistics : [
|
|
{
|
|
"StatisticName": "Dragon",
|
|
"Value": args.Lv
|
|
}
|
|
]});
|
|
|
|
return {
|
|
error: error
|
|
}
|
|
}
|
|
|
|
handlers.Check_CanBuyInapp = function(args)
|
|
{ // 인앱 구매전 에러 확인용
|
|
return {
|
|
error: Get_Error(args.Token)
|
|
}
|
|
}
|
|
|
|
handlers.Del_TitlePlayer = function(args)
|
|
{
|
|
if(!CheckNullOrEmpty(args.Agree))
|
|
{
|
|
var playerprofile = entity.GetTitlePlayersFromMasterPlayerAccountIds({ MasterPlayerAccountIds: [currentPlayerId]});
|
|
var titleId = playerprofile.TitlePlayerAccounts[currentPlayerId].Id;
|
|
|
|
log.info("순위표를 지웁니다.");
|
|
progression.DeleteLeaderboardEntries({ Name: "Rank_Maze", EntityIds: [titleId]});
|
|
|
|
log.info("타이틀 계정을 지웁니다.");
|
|
server.DeletePlayer({PlayFabId: currentPlayerId});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
handlers.Rank_Reward = function(args)
|
|
{
|
|
// 현재 버전 확인
|
|
var cur = progression.GetLeaderboardDefinition({ Name: args.LeaderboardName });
|
|
//log.info("현재 버전 : " + cur.Version);
|
|
|
|
var playerprofile = entity.GetTitlePlayersFromMasterPlayerAccountIds({ MasterPlayerAccountIds: [currentPlayerId]});
|
|
var titleId = playerprofile.TitlePlayerAccounts[currentPlayerId].Id;
|
|
//log.info("titleId : " + titleId);
|
|
|
|
// 이전 버전에서 내 순위 확인
|
|
var a = progression.GetLeaderboardAroundEntity({ LeaderboardName: args.LeaderboardName, MaxSurroundingEntries: 1,
|
|
Version: cur.Version - 1, Entity: { Id : titleId, Type: "title_player_account" } });
|
|
//log.info("a : " + JSON.stringify(a));
|
|
|
|
for (var i in a.Rankings)
|
|
{
|
|
//log.info("ranker id : " + a.Rankings[i].Entity.Id);
|
|
if (a.Rankings[i].Entity.Id == titleId)
|
|
{
|
|
//log.info("나의 랭킹 : " + a.Rankings[i].Rank);
|
|
|
|
// 현재 날짜 가져오기
|
|
const now = new Date();
|
|
const month = now.getMonth() + 1; // getMonth()는 0부터 시작하므로 +1
|
|
const day = now.getDate(); // getDate()는 1~31 반환
|
|
const rank = a.Rankings[i].Rank; // 리더보드에서 가져온 순위 값
|
|
|
|
var maildata = {};
|
|
maildata.Day = 7;
|
|
maildata.ItemID = 1;
|
|
maildata.Amount = 10; // TOOD 정인호 : 순위에 따라 지급
|
|
maildata.Msg = formatString(args.Msg, [month, day, rank]);
|
|
Add_Mail(maildata);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
handlers.Send_Cheat = function()
|
|
{
|
|
server.UpdateUserReadOnlyData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"Cheat": "Use" } });
|
|
server.UpdatePlayerStatistics({PlayFabId: currentPlayerId, Statistics : [
|
|
{
|
|
"StatisticName": "Best Stage",
|
|
"Value": 1
|
|
},
|
|
{
|
|
"StatisticName": "WeeklyPvP",
|
|
"Value": 0
|
|
},
|
|
{
|
|
"StatisticName": "BossRaid",
|
|
"Value": 0
|
|
},
|
|
{
|
|
"StatisticName": "Reset Best Stage",
|
|
"Value": 0
|
|
}
|
|
]});
|
|
}
|
|
|
|
handlers.Use_Coupon = function(args)
|
|
{
|
|
log.info(args.Coupon);
|
|
|
|
var error = Get_Error(args.Token);
|
|
if(error < 0) return {error:error};
|
|
|
|
var userdata = server.GetUserData({ PlayFabId: currentPlayerId }).Data;
|
|
var couponinfo = [];
|
|
if(!CheckNullOrEmpty(userdata.CouponInfo)) couponinfo = JSON.parse(userdata.CouponInfo.Value);
|
|
|
|
var coupontable = Get_CouponTable();
|
|
var findcoupon = coupontable.find(f=>f.Coupon == args.Coupon);
|
|
if(findcoupon != null)
|
|
{ // 전체 쿠폰
|
|
var nowtime = Get_CurKoreaTime();
|
|
var starttime = new Date(findcoupon.StartTime);
|
|
var endtime = new Date(findcoupon.EndTime);
|
|
|
|
if(nowtime - starttime > 0 && endtime - nowtime > 0)
|
|
{
|
|
var find = couponinfo.find(f=>f == findcoupon.Index);
|
|
if(find == null)
|
|
{
|
|
// 참여 여부 저장
|
|
couponinfo.push(findcoupon.Index);
|
|
server.UpdateUserData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"CouponInfo": JSON.stringify(couponinfo)} });
|
|
|
|
// 보상 지급
|
|
var RtnValue = [];
|
|
var makereward = {};
|
|
|
|
var reward1 = findcoupon.Reward1.split(',');
|
|
makereward.Reward = reward1[0];
|
|
makereward.RewardAmount = reward1[1];
|
|
RtnValue.push(makereward);
|
|
|
|
var reward2 = [];
|
|
if(!CheckNullOrEmpty(findcoupon.Reward2))
|
|
{
|
|
makereward = {};
|
|
reward2 = findcoupon.Reward2.split(',');
|
|
makereward.Reward = reward2[0];
|
|
makereward.RewardAmount = reward2[1];
|
|
RtnValue.push(makereward);
|
|
}
|
|
|
|
return {
|
|
error: error,
|
|
Rewards: '{"Rewards":' + JSON.stringify(RtnValue) + '}'
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
error: 4
|
|
};
|
|
}
|
|
|
|
handlers.Send_Push = function(args)
|
|
{
|
|
var urod = server.GetUserReadOnlyData({ PlayFabId: currentPlayerId }).Data;
|
|
var common = JSON.parse(urod.UserInfo.Value).Common;
|
|
var isSendAgree = false;
|
|
var profile = server.GetPlayerProfile( {PlayFabId: currentPlayerId, ProfileConstraints: {ShowLocations: true}} );
|
|
if (profile.PlayerProfile.Locations[profile.PlayerProfile.Locations.length - 1].CountryCode == "KR")
|
|
{
|
|
var dt = new Date();
|
|
dt.setHours(dt.getHours() + 9);
|
|
if(dt.getHours() >= 8 && dt.getHours() <= 21)
|
|
isSendAgree = common.NotificationAgreeDaytime;
|
|
else
|
|
isSendAgree = common.NotificationAgreeNighttime;
|
|
}
|
|
|
|
if (isSendAgree)
|
|
{ // try to send push notification
|
|
try
|
|
{
|
|
server.SendPushNotification(
|
|
{
|
|
Recipient : currentPlayerId,
|
|
Package :
|
|
{
|
|
Message : args.Msg,
|
|
Title: args.Title
|
|
}
|
|
});
|
|
}
|
|
catch (ex)
|
|
{
|
|
log.info("Target player has not registered for Push Notifications");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handlers.CafeEvent_Lv5 = function(args)
|
|
{
|
|
var userdata = server.GetUserData({ PlayFabId: currentPlayerId }).Data;
|
|
var eventinfo = [];
|
|
if(!CheckNullOrEmpty(userdata.EventInfo)) eventinfo = JSON.parse(userdata.EventInfo.Value);
|
|
|
|
var find = eventinfo.find(f=>f.Event == "Lv10");
|
|
if(find == null)
|
|
{
|
|
// 참여 여부 저장
|
|
var eventwrite = {};
|
|
eventwrite.Event = "Lv10";
|
|
eventinfo.push(eventwrite);
|
|
server.UpdateUserData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"EventInfo": JSON.stringify(eventinfo)} });
|
|
|
|
var mail = {};
|
|
mail.Reward = "Gem";
|
|
mail.RewardAmount = 2000;
|
|
mail.Msg = "공식카페 마녀 레벨5 달성 이벤트 보상";
|
|
Add_Mail(mail);
|
|
|
|
log.info("Lv5 보상 지급");
|
|
}
|
|
else
|
|
log.info("Lv5 보상을 이미 지급한 유저입니다.");
|
|
}
|
|
handlers.CafeEvent_SNS = function(args)
|
|
{
|
|
var userdata = server.GetUserData({ PlayFabId: currentPlayerId }).Data;
|
|
var eventinfo = [];
|
|
if(!CheckNullOrEmpty(userdata.EventInfo)) eventinfo = JSON.parse(userdata.EventInfo.Value);
|
|
|
|
var find = eventinfo.find(f=>f.Event == "SNS");
|
|
if(find == null)
|
|
{
|
|
// 참여 여부 저장
|
|
var eventwrite = {};
|
|
eventwrite.Event = "SNS";
|
|
eventinfo.push(eventwrite);
|
|
server.UpdateUserData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"EventInfo": JSON.stringify(eventinfo)} });
|
|
|
|
var mail = {};
|
|
mail.Reward = "Gem";
|
|
mail.RewardAmount = 10000;
|
|
mail.Msg = "SNS 이벤트 보상입니다.";
|
|
Add_Mail(mail);
|
|
|
|
log.info("SNS 보상 지급");
|
|
}
|
|
else
|
|
log.info("SNS 보상을 이미 지급한 유저입니다.");
|
|
}
|
|
handlers.CafeEvent_Greeting = function(args)
|
|
{
|
|
var userdata = server.GetUserData({ PlayFabId: currentPlayerId }).Data;
|
|
var eventinfo = [];
|
|
if(!CheckNullOrEmpty(userdata.EventInfo)) eventinfo = JSON.parse(userdata.EventInfo.Value);
|
|
|
|
var find = eventinfo.find(f=>f.Event == "Greeting");
|
|
if(find == null)
|
|
{
|
|
// 참여 여부 저장
|
|
var eventwrite = {};
|
|
eventwrite.Event = "Greeting";
|
|
eventinfo.push(eventwrite);
|
|
server.UpdateUserData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"EventInfo": JSON.stringify(eventinfo)} });
|
|
|
|
var mail = {};
|
|
mail.Reward = "Gem";
|
|
mail.RewardAmount = 3000;
|
|
mail.Msg = "공식카페 이벤트 오픈 전 인사 보상입니다.";
|
|
Add_Mail(mail);
|
|
|
|
log.info("오픈 전 인사 보상 지급");
|
|
}
|
|
else
|
|
log.info("오픈 전 인사 보상을 이미 지급한 유저입니다.");
|
|
}
|
|
handlers.CafeEvent_MyFarm = function(args)
|
|
{
|
|
var userdata = server.GetUserData({ PlayFabId: currentPlayerId }).Data;
|
|
var eventinfo = [];
|
|
if(!CheckNullOrEmpty(userdata.EventInfo)) eventinfo = JSON.parse(userdata.EventInfo.Value);
|
|
|
|
var find = eventinfo.find(f=>f.Event == "MyFarm");
|
|
if(find == null)
|
|
{
|
|
// 참여 여부 저장
|
|
var eventwrite = {};
|
|
eventwrite.Event = "MyFarm";
|
|
eventinfo.push(eventwrite);
|
|
server.UpdateUserData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"EventInfo": JSON.stringify(eventinfo)} });
|
|
|
|
var mail = {};
|
|
mail.Reward = "Inven";
|
|
mail.ID = 50;
|
|
mail.RewardAmount = 50;
|
|
mail.Msg = "마이팜 인증 보상입니다.";
|
|
Add_Mail(mail);
|
|
|
|
log.info("마이팜 인증 보상 지급");
|
|
}
|
|
else
|
|
log.info("마이팜 인증 보상을 이미 지급한 유저입니다.");
|
|
}
|
|
|
|
handlers.SendMail_DailyInit = function(args)
|
|
{
|
|
var maildata = {};
|
|
maildata.Reward = "DailyInit";
|
|
maildata.RewardAmount = 0;
|
|
maildata.Msg = "일일 초기화 아이템\n바로 사용해주세요!!";
|
|
maildata.Day = 1;
|
|
Add_Mail(maildata);
|
|
}
|
|
|
|
handlers.CheckError = function(args)
|
|
{
|
|
var urod = server.GetUserReadOnlyData({ PlayFabId: currentPlayerId }).Data;
|
|
var uinfo = JSON.parse(urod.UserInfo.Value);
|
|
|
|
var existnull = false;
|
|
for(var i in uinfo.Common)
|
|
{
|
|
if(uinfo.Common[i] == null)
|
|
{
|
|
uinfo.Common[i] = 0;
|
|
existnull = true;
|
|
}
|
|
}
|
|
|
|
if(existnull)
|
|
server.UpdateUserReadOnlyData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"UserInfo": JSON.stringify(uinfo)} });
|
|
|
|
/*
|
|
if(uinfo.Money[3] < 0)
|
|
{
|
|
var gem1 = JSON.parse(server.GetTitleInternalData("StoneMinus").Data.StoneMinus);
|
|
gem1.push(currentPlayerId);
|
|
server.SetTitleInternalData({ PlayFabId: currentPlayerId, Key: "StoneMinus", Value: JSON.stringify(gem1) });
|
|
}
|
|
|
|
if(uinfo.Money[0] < 0)
|
|
{
|
|
var gem1 = JSON.parse(server.GetTitleInternalData("GemMinus").Data.GemMinus);
|
|
gem1.push(currentPlayerId);
|
|
server.SetTitleInternalData({ PlayFabId: currentPlayerId, Key: "GemMinus", Value: JSON.stringify(gem1) });
|
|
}
|
|
*/
|
|
}
|
|
|
|
handlers.Update_BackUp = function(args)
|
|
{
|
|
BackUpUserInfo();
|
|
}
|
|
function BackUpUserInfo()
|
|
{
|
|
var urod = server.GetUserReadOnlyData({ PlayFabId: currentPlayerId }).Data;
|
|
var uinfo = JSON.parse(urod.UserInfo.Value);
|
|
var uprod = server.GetUserPublisherData({ PlayFabId: currentPlayerId }).Data;
|
|
var index = 1;
|
|
if(CheckNullOrEmpty(uprod.Key))
|
|
{
|
|
index = 1;
|
|
}
|
|
else
|
|
index = uprod.Key.Value;
|
|
|
|
if(index == 1)
|
|
server.UpdateUserPublisherReadOnlyData({ PlayFabId: currentPlayerId, Data: { UserInfo1 : JSON.stringify(uinfo)} });
|
|
else if(index == 2)
|
|
server.UpdateUserPublisherReadOnlyData({ PlayFabId: currentPlayerId, Data: { UserInfo2 : JSON.stringify(uinfo)} });
|
|
else if(index == 3)
|
|
server.UpdateUserPublisherReadOnlyData({ PlayFabId: currentPlayerId, Data: { UserInfo3 : JSON.stringify(uinfo)} });
|
|
else if(index == 4)
|
|
server.UpdateUserPublisherReadOnlyData({ PlayFabId: currentPlayerId, Data: { UserInfo4 : JSON.stringify(uinfo)} });
|
|
else if(index == 5)
|
|
server.UpdateUserPublisherReadOnlyData({ PlayFabId: currentPlayerId, Data: { UserInfo5 : JSON.stringify(uinfo)} });
|
|
else if(index == 6)
|
|
server.UpdateUserPublisherReadOnlyData({ PlayFabId: currentPlayerId, Data: { UserInfo6 : JSON.stringify(uinfo)} });
|
|
else if(index == 7)
|
|
server.UpdateUserPublisherReadOnlyData({ PlayFabId: currentPlayerId, Data: { UserInfo7 : JSON.stringify(uinfo)} });
|
|
else if(index == 8)
|
|
server.UpdateUserPublisherReadOnlyData({ PlayFabId: currentPlayerId, Data: { UserInfo8 : JSON.stringify(uinfo)} });
|
|
else if(index == 9)
|
|
server.UpdateUserPublisherReadOnlyData({ PlayFabId: currentPlayerId, Data: { UserInfo9 : JSON.stringify(uinfo)} });
|
|
|
|
++index;
|
|
if(index > 9) index = 1;
|
|
server.UpdateUserPublisherData({ PlayFabId: currentPlayerId, Data: { Key : index } });
|
|
}
|
|
|
|
handlers.Update_Mail = function(args)
|
|
{
|
|
// 점검 보상 우편
|
|
var makemail = {};
|
|
makemail.Reward = "Gem";
|
|
makemail.RewardAmount = 500;
|
|
var kortime = Get_CurKoreaTime();
|
|
makemail.Msg = (kortime.getMonth() + 1) + '월 ' + kortime.getDate() + '일 점검 보상입니다.';
|
|
makemail.Day = 1;
|
|
Add_Mail(makemail);
|
|
|
|
//if(!CheckNullOrEmpty(urod.EventInfo))
|
|
//{
|
|
// server.UpdateUserReadOnlyData({ PlayFabId: currentPlayerId, Data: {"EventInfo": null} });
|
|
//}
|
|
}
|
|
|
|
handlers.CheckOtherData = function(args)
|
|
{
|
|
var uidata = server.GetUserInternalData({ PlayFabId: args.ID }).Data;
|
|
if(!CheckNullOrEmpty(uidata.BanUser))
|
|
return {
|
|
error: -2
|
|
};
|
|
|
|
var error = 0;
|
|
var urod = server.GetUserReadOnlyData({ PlayFabId: args.ID }).Data.UserInfo.Value;
|
|
var json = JSON.parse(urod);
|
|
if(json.Common[49] == 0 || json.Common[49] != args.PW)
|
|
error = -1;
|
|
|
|
return {
|
|
error: error,
|
|
};
|
|
}
|
|
handlers.GetOtherData = function(args)
|
|
{
|
|
server.UpdateUserInternalData({ PlayFabId: args.ID, Permission: "Public", Data: {"BanUser": 1 } });
|
|
|
|
var urod = server.GetUserReadOnlyData({ PlayFabId: args.ID }).Data.UserInfo.Value;
|
|
var json = JSON.parse(urod);
|
|
json.Common[49] = 0;
|
|
server.UpdateUserReadOnlyData({ PlayFabId: currentPlayerId, Permission: "Public", Data: {"UserInfo": JSON.stringify(json)} });
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function Get_Inventory()
|
|
{
|
|
return server.GetUserInventory({ PlayFabId: currentPlayerId });
|
|
}
|
|
function Get_Tables()
|
|
{
|
|
return server.GetTitleInternalData({ Keys: null }).Data;
|
|
}
|
|
function Get_TitleData()
|
|
{
|
|
return server.GetTitleData({ Keys: null }).Data;
|
|
}
|
|
function Get_PvPVersion()
|
|
{
|
|
var result = server.GetLeaderboard({
|
|
StatisticName: "WeeklyPvP",
|
|
StartPosition: 0,
|
|
MaxResultsCount: 0
|
|
});
|
|
|
|
return result.Version;
|
|
}
|
|
function Get_CouponTable()
|
|
{
|
|
var table = JSON.parse(server.GetTitleInternalData("CouponTable").Data.CouponTable);
|
|
return table.servertable_coupon;
|
|
}
|
|
function Get_ItemTable()
|
|
{
|
|
var titleData = server.GetTitleInternalData({ Keys: ["ItemTable"] });
|
|
return JSON.parse(titleData.Data.ItemTable);
|
|
}
|
|
function Get_ShopTable()
|
|
{
|
|
var titleData = server.GetTitleInternalData({ Keys: ["ShopTable"] });
|
|
return JSON.parse(titleData.Data.ShopTable);
|
|
}
|
|
function Get_MissionTable()
|
|
{
|
|
var titleData = server.GetTitleInternalData({ Keys: ["MissionTable"] });
|
|
return JSON.parse(titleData.Data.MissionTable);
|
|
}
|
|
function Get_AbilityConfigTable()
|
|
{
|
|
var titleData = server.GetTitleInternalData({ Keys: ["AbilityConfigData"] });
|
|
return JSON.parse(titleData.Data.AbilityConfigData);
|
|
}
|
|
function Get_ClassOpenTable()
|
|
{
|
|
return [
|
|
{
|
|
"n_ClassID": "10501",
|
|
"n_linkedClass1": "0",
|
|
"n_linkedClass2": "0",
|
|
"n_RequireAbility": "0",
|
|
"e_RequireAwakenType1": "STR",
|
|
"n_RequireAwakenStep1": "0",
|
|
"e_RequireAwakenType2": "None",
|
|
"n_RequireAwakenStep2": "0",
|
|
"n_NeedGoodsCount": "1",
|
|
"n_ClassOpenMission": "0"
|
|
},
|
|
{
|
|
"n_ClassID": "10101",
|
|
"n_linkedClass1": "10501",
|
|
"n_linkedClass2": "0",
|
|
"n_RequireAbility": "0",
|
|
"e_RequireAwakenType1": "None",
|
|
"n_RequireAwakenStep1": "0",
|
|
"e_RequireAwakenType2": "None",
|
|
"n_RequireAwakenStep2": "0",
|
|
"n_NeedGoodsCount": "1",
|
|
"n_ClassOpenMission": "1"
|
|
},
|
|
{
|
|
"n_ClassID": "10401",
|
|
"n_linkedClass1": "10501",
|
|
"n_linkedClass2": "0",
|
|
"n_RequireAbility": "0",
|
|
"e_RequireAwakenType1": "STR",
|
|
"n_RequireAwakenStep1": "0",
|
|
"e_RequireAwakenType2": "None",
|
|
"n_RequireAwakenStep2": "0",
|
|
"n_NeedGoodsCount": "1",
|
|
"n_ClassOpenMission": "2"
|
|
},
|
|
{
|
|
"n_ClassID": "10301",
|
|
"n_linkedClass1": "10501",
|
|
"n_linkedClass2": "0",
|
|
"n_RequireAbility": "0",
|
|
"e_RequireAwakenType1": "STR",
|
|
"n_RequireAwakenStep1": "0",
|
|
"e_RequireAwakenType2": "None",
|
|
"n_RequireAwakenStep2": "0",
|
|
"n_NeedGoodsCount": "1",
|
|
"n_ClassOpenMission": "3"
|
|
},
|
|
{
|
|
"n_ClassID": "10502",
|
|
"n_linkedClass1": "10101",
|
|
"n_linkedClass2": "0",
|
|
"n_RequireAbility": "0",
|
|
"e_RequireAwakenType1": "DEX",
|
|
"n_RequireAwakenStep1": "0",
|
|
"e_RequireAwakenType2": "None",
|
|
"n_RequireAwakenStep2": "0",
|
|
"n_NeedGoodsCount": "1",
|
|
"n_ClassOpenMission": "4"
|
|
},
|
|
{
|
|
"n_ClassID": "10601",
|
|
"n_linkedClass1": "10101",
|
|
"n_linkedClass2": "0",
|
|
"n_RequireAbility": "0",
|
|
"e_RequireAwakenType1": "INT",
|
|
"n_RequireAwakenStep1": "0",
|
|
"e_RequireAwakenType2": "None",
|
|
"n_RequireAwakenStep2": "0",
|
|
"n_NeedGoodsCount": "1",
|
|
"n_ClassOpenMission": "5"
|
|
},
|
|
{
|
|
"n_ClassID": "10201",
|
|
"n_linkedClass1": "10101",
|
|
"n_linkedClass2": "10401",
|
|
"n_RequireAbility": "0",
|
|
"e_RequireAwakenType1": "DEX",
|
|
"n_RequireAwakenStep1": "0",
|
|
"e_RequireAwakenType2": "None",
|
|
"n_RequireAwakenStep2": "0",
|
|
"n_NeedGoodsCount": "1",
|
|
"n_ClassOpenMission": "6"
|
|
},
|
|
{
|
|
"n_ClassID": "10402",
|
|
"n_linkedClass1": "10401",
|
|
"n_linkedClass2": "0",
|
|
"n_RequireAbility": "0",
|
|
"e_RequireAwakenType1": "DEX",
|
|
"n_RequireAwakenStep1": "0",
|
|
"e_RequireAwakenType2": "None",
|
|
"n_RequireAwakenStep2": "0",
|
|
"n_NeedGoodsCount": "1",
|
|
"n_ClassOpenMission": "7"
|
|
},
|
|
{
|
|
"n_ClassID": "10202",
|
|
"n_linkedClass1": "10401",
|
|
"n_linkedClass2": "0",
|
|
"n_RequireAbility": "0",
|
|
"e_RequireAwakenType1": "INT",
|
|
"n_RequireAwakenStep1": "0",
|
|
"e_RequireAwakenType2": "None",
|
|
"n_RequireAwakenStep2": "0",
|
|
"n_NeedGoodsCount": "1",
|
|
"n_ClassOpenMission": "8"
|
|
},
|
|
{
|
|
"n_ClassID": "10102",
|
|
"n_linkedClass1": "10401",
|
|
"n_linkedClass2": "10301",
|
|
"n_RequireAbility": "0",
|
|
"e_RequireAwakenType1": "STR",
|
|
"n_RequireAwakenStep1": "0",
|
|
"e_RequireAwakenType2": "None",
|
|
"n_RequireAwakenStep2": "0",
|
|
"n_NeedGoodsCount": "1",
|
|
"n_ClassOpenMission": "9"
|
|
},
|
|
{
|
|
"n_ClassID": "10302",
|
|
"n_linkedClass1": "10301",
|
|
"n_linkedClass2": "0",
|
|
"n_RequireAbility": "0",
|
|
"e_RequireAwakenType1": "DEX",
|
|
"n_RequireAwakenStep1": "0",
|
|
"e_RequireAwakenType2": "None",
|
|
"n_RequireAwakenStep2": "0",
|
|
"n_NeedGoodsCount": "1",
|
|
"n_ClassOpenMission": "10"
|
|
},
|
|
{
|
|
"n_ClassID": "10303",
|
|
"n_linkedClass1": "10301",
|
|
"n_linkedClass2": "0",
|
|
"n_RequireAbility": "0",
|
|
"e_RequireAwakenType1": "INT",
|
|
"n_RequireAwakenStep1": "0",
|
|
"e_RequireAwakenType2": "None",
|
|
"n_RequireAwakenStep2": "0",
|
|
"n_NeedGoodsCount": "1",
|
|
"n_ClassOpenMission": "11"
|
|
}
|
|
]
|
|
}
|
|
function Get_GlobalValueTable()
|
|
{
|
|
return [
|
|
{
|
|
"s_ID": "n_CashItemID",
|
|
"n_Value": "1",
|
|
"exception": "캐쉬 아이템 id"
|
|
},
|
|
{
|
|
"s_ID": "n_JewelItemID",
|
|
"n_Value": "3",
|
|
"exception": "보석 아이템 id"
|
|
},
|
|
{
|
|
"s_ID": "ATK",
|
|
"n_Value": "1",
|
|
"exception": "sss"
|
|
},
|
|
{
|
|
"s_ID": "HP",
|
|
"n_Value": "100",
|
|
"exception": "sss"
|
|
},
|
|
{
|
|
"s_ID": "DEF",
|
|
"n_Value": "1",
|
|
"exception": "sss"
|
|
},
|
|
{
|
|
"s_ID": "M_DEF",
|
|
"n_Value": "1",
|
|
"exception": "sss"
|
|
},
|
|
{
|
|
"s_ID": "ATK_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": "sss"
|
|
},
|
|
{
|
|
"s_ID": "HP_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": "sss"
|
|
},
|
|
{
|
|
"s_ID": "DEF_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": "sss"
|
|
},
|
|
{
|
|
"s_ID": "M_DEF_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": "sss"
|
|
},
|
|
{
|
|
"s_ID": "MP",
|
|
"n_Value": "30",
|
|
"exception": "sss"
|
|
},
|
|
{
|
|
"s_ID": "MP_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": "sss"
|
|
},
|
|
{
|
|
"s_ID": "ATK_FIXED",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "ATK_FIXED_DECREASE",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "CRI",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "CRI_DMG_Multiplier",
|
|
"n_Value": "10",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "M_CRI",
|
|
"n_Value": "100",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "M_CRI_DMG_Multiplier",
|
|
"n_Value": "0.1",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "SKILL_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "COOLTIME_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "HERO_ATK_SPD",
|
|
"n_Value": "0.75",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "ATK_SPD_Multiplier",
|
|
"n_Value": "1",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "HERO_MOVE_SPD",
|
|
"n_Value": "3",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "MOVE_SPD_Multiplier",
|
|
"n_Value": "1",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "HP_REGEN",
|
|
"n_Value": "1",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "MP_REGEN",
|
|
"n_Value": "3",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "HP_REGEN_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "MP_REGEN_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "PIERCING_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "DMG_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "GOLD_INCREASE",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "GOLD_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "EXP_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "ITEM_Multiplier",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "EnchantOpenLv1",
|
|
"n_Value": "0",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "EnchantOpenLv2",
|
|
"n_Value": "10",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "EnchantOpenLv3",
|
|
"n_Value": "20",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "Defense_Coefficient",
|
|
"n_Value": "6",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "f_PC_FindEnemyRange",
|
|
"n_Value": "6",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "f_Pet_FindEnemyRange",
|
|
"n_Value": "5",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "f_AvoidCoolTime",
|
|
"n_Value": "5",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "f_KnockbackTime",
|
|
"n_Value": "0.02",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "f_SkillTeamRange",
|
|
"n_Value": "15",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_AbilityMaterialID",
|
|
"n_Value": "444",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_JobMaterialID",
|
|
"n_Value": "445",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "AWAKEN_GOODS_UPGRADE",
|
|
"n_Value": "450",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "AWAKEN_GOODS_STR",
|
|
"n_Value": "451",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "AWAKEN_GOODS_DEX",
|
|
"n_Value": "452",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "AWAKEN_GOODS_INT",
|
|
"n_Value": "453",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "AWAKEN_GOODS_LUK",
|
|
"n_Value": "454",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "AWAKEN_GOODS_ALL",
|
|
"n_Value": "455",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_BreakingLimitSlotMaterialID",
|
|
"n_Value": "461",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_FirstEquipPet",
|
|
"n_Value": "50002",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_PetReinforceMaterialID",
|
|
"n_Value": "441",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_PetReinforcePriceOptionID1",
|
|
"n_Value": "340001",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_PetReinforcePriceOptionID2",
|
|
"n_Value": "340002",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_PetReinforcePriceOptionID3",
|
|
"n_Value": "340003",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_PetSkillAwaken_Lv1",
|
|
"n_Value": "10",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_PetSkillAwaken_Lv2",
|
|
"n_Value": "20",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_PetSkillAwaken_Lv3",
|
|
"n_Value": "40",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_EssenceMileageID",
|
|
"n_Value": "471",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_EssenceRandomBagID",
|
|
"n_Value": "9800001",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_RelicMaxStar",
|
|
"n_Value": "5",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_RelicReinforceMaterialID",
|
|
"n_Value": "472",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_FarmSeedID",
|
|
"n_Value": "456",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_FarmPlantingSeedAmount",
|
|
"n_Value": "5",
|
|
"exception": ""
|
|
},
|
|
{
|
|
"s_ID": "n_FirstClassID",
|
|
"n_Value": "10501",
|
|
"exception": "최초 시작 직업"
|
|
},
|
|
{
|
|
"s_ID": "MazeMapCount",
|
|
"n_Value": "2",
|
|
"exception": "미궁 맵 개수"
|
|
},
|
|
{
|
|
"s_ID": "GoldDropRandomRange",
|
|
"n_Value": "0.1",
|
|
"exception": "몬스터 드랍 골드양 범위"
|
|
},
|
|
{
|
|
"s_ID": "n_Benefit1Count",
|
|
"n_Value": "10",
|
|
"exception": "뽑기 혜택1 횟수"
|
|
},
|
|
{
|
|
"s_ID": "n_Benefit2Count",
|
|
"n_Value": "50",
|
|
"exception": "뽑기 혜택2 횟수"
|
|
},
|
|
{
|
|
"s_ID": "n_Benefit1Grade",
|
|
"n_Value": "4",
|
|
"exception": "뽑기 혜택1 등급"
|
|
},
|
|
{
|
|
"s_ID": "n_Benefit2Grade",
|
|
"n_Value": "5",
|
|
"exception": "뽑기 혜택2 등급"
|
|
}
|
|
];
|
|
}
|
|
function Get_AwakenUpgradeTable()
|
|
{
|
|
return [
|
|
{
|
|
"n_AwakenStep": "1",
|
|
"n_MaxUpgradeLevel": "10",
|
|
"n_AwakenGoodsCost": "1",
|
|
"n_DefaultUpgradeCostValue": "3",
|
|
"f_CountPerUpgradeCostValue": "1.5",
|
|
"f_BalanceConstant": "0.032"
|
|
},
|
|
{
|
|
"n_AwakenStep": "2",
|
|
"n_MaxUpgradeLevel": "25",
|
|
"n_AwakenGoodsCost": "2",
|
|
"n_DefaultUpgradeCostValue": "4",
|
|
"f_CountPerUpgradeCostValue": "1.5",
|
|
"f_BalanceConstant": "0.032"
|
|
},
|
|
{
|
|
"n_AwakenStep": "3",
|
|
"n_MaxUpgradeLevel": "30",
|
|
"n_AwakenGoodsCost": "3",
|
|
"n_DefaultUpgradeCostValue": "5",
|
|
"f_CountPerUpgradeCostValue": "1.5",
|
|
"f_BalanceConstant": "0.032"
|
|
}
|
|
];
|
|
}
|
|
function Get_PlayOCoupons()
|
|
{
|
|
var poc = JSON.parse(server.GetTitleInternalData("PlayO").Data.PlayO);
|
|
return poc.Coupons;
|
|
}
|
|
function Get_CurKoreaTime()
|
|
{
|
|
var curServerTime = new Date();
|
|
return new Date(curServerTime.setHours(curServerTime.getHours() + 9));
|
|
}
|
|
function CheckNullOrEmpty(value)
|
|
{
|
|
if (value == "" || value == null || value == undefined || (value != null && typeof value == "object" && !Object.keys(value).length))
|
|
return true;
|
|
return false;
|
|
}
|
|
function getRandomFloat(min, max) { return Math.random() * (max - min) + min; }
|
|
function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
|
|
function sleep(milliseconds)
|
|
{
|
|
const date = Date.now();
|
|
let currentDate = null;
|
|
do {
|
|
currentDate = Date.now();
|
|
} while (currentDate - date < milliseconds);
|
|
}
|
|
function formatString(template, values) { return template.replace(/{(\d+)}/g, (match, index) => values[index] || match); } |