Project_WL/Assets/PlayFabEditorExtensions/Editor/Resources/.CloudScript.js

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