api: 규격 정의
This commit is contained in:
+90
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
try {
|
||||
$input = json_decode(file_get_contents('php://input'));
|
||||
} catch (\Exception $e) {
|
||||
Json::dieWithReason($e->getMessage());
|
||||
}
|
||||
|
||||
if (!key_exists('path', $input)) {
|
||||
Json::dieWithReason('path가 지정되지 않았습니다.');
|
||||
}
|
||||
|
||||
if (key_exists('args', $input) && !is_array($input['args'])) {
|
||||
Json::dieWithReason('args가 array가 아닙니다.' . gettype($input['args']));
|
||||
}
|
||||
|
||||
try {
|
||||
$obj = buildAPIExecutorClass($input['path'], $input['args'] ?? []);
|
||||
$api =
|
||||
$validateResult = $obj->validateArgs();
|
||||
if ($validateResult !== null) {
|
||||
Json::dieWithReason($validateResult);
|
||||
}
|
||||
|
||||
$sessionMode = $obj->getRequiredSessionMode();
|
||||
if ($sessionMode === BaseAPI::NO_SESSION) {
|
||||
$session = null;
|
||||
} else {
|
||||
if ($sessionMode & BaseAPI::REQ_GAME_LOGIN) {
|
||||
$session = Session::requireGameLogin();
|
||||
} else if ($sessionMode & BaseAPI::REQ_LOGIN) {
|
||||
$session = Session::requireLogin();
|
||||
} else {
|
||||
Json::dieWithReason("올바르지 않은 SessionMode: {$sessionMode}");
|
||||
}
|
||||
|
||||
if ($sessionMode & BaseAPI::REQ_READ_ONLY) {
|
||||
$session->setReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
$modifiedSince = isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
|
||||
? new \DateTimeImmutable($_SERVER['HTTP_IF_MODIFIED_SINCE'], new \DateTimeZone("UTC"))
|
||||
: null;
|
||||
$reqEtags = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : null;
|
||||
|
||||
$result = $obj->launch($session, $modifiedSince, $reqEtags);
|
||||
if (is_string($result)) {
|
||||
Json::dieWithReason($result);
|
||||
}
|
||||
|
||||
$cacheResult = $obj->tryCache();
|
||||
if ($cacheResult !== null) {
|
||||
/** @var \DateTimeInterface $lastModified */
|
||||
[$lastModified, $etag] = $cacheResult;
|
||||
|
||||
if ($lastModified !== null) {
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s", TimeUtil::DateTimeToSeconds($lastModified, true)) . " GMT");
|
||||
}
|
||||
if ($etag !== null) {
|
||||
header("Etag: $etag");
|
||||
}
|
||||
|
||||
if ($modifiedSince !== null && $lastModified !== null && TimeUtil::DateIntervalToSeconds($modifiedSince->diff($lastModified)) == 0) {
|
||||
header("HTTP/1.1 304 Not Modified");
|
||||
die();
|
||||
}
|
||||
if ($reqEtags !== null && $reqEtags === $etag) {
|
||||
header("HTTP/1.1 304 Not Modified");
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
if ($result === null) {
|
||||
Json::die([
|
||||
'result' => true,
|
||||
'reason' => 'success'
|
||||
], $cacheResult === null ? Json::NO_CACHE : 0);
|
||||
}
|
||||
Json::die($result, $cacheResult === null ? Json::NO_CACHE : 0);
|
||||
} catch (\Exception $e) {
|
||||
Json::dieWithReason($e->getMessage());
|
||||
} catch (mixed $e) {
|
||||
Json::dieWithReason($e);
|
||||
}
|
||||
@@ -1,393 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
$input = json_decode(file_get_contents('php://input'));
|
||||
|
||||
|
||||
$v = new Validator($input);
|
||||
$v
|
||||
->rule('required', [
|
||||
'name',
|
||||
'leadership',
|
||||
'strength',
|
||||
'intel',
|
||||
'pic',
|
||||
'character',
|
||||
])
|
||||
->rule('integer', [
|
||||
'leadership',
|
||||
'strength',
|
||||
'intel',
|
||||
'inheritTurntime',
|
||||
])
|
||||
->rule('boolean', [
|
||||
'pic'
|
||||
])
|
||||
->rule('stringWidthBetween', 'name', 1, 18)
|
||||
->rule('min', [
|
||||
'leadership',
|
||||
'strength',
|
||||
'intel'
|
||||
], GameConst::$defaultStatMin)
|
||||
->rule('max', [
|
||||
'leadership',
|
||||
'strength',
|
||||
'intel'
|
||||
], GameConst::$defaultStatMax)
|
||||
->rule('in', 'character', array_merge(GameConst::$availablePersonality, ['Random']))
|
||||
->rule('in', 'inheritSpecial', GameConst::$availableSpecialWar)
|
||||
->rule('min', 'inheritTurntime', 0)
|
||||
->rule('in', 'inheritCity', array_keys(CityConst::all()))
|
||||
->rule('integerArray', 'inheritBonusStat');
|
||||
|
||||
if (!$v->validate()) {
|
||||
Json::dieWithReason($v->errorStr());
|
||||
}
|
||||
|
||||
$session = Session::requireLogin()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
//NOTE: 이 페이지에서는 세션에 데이터를 등록하지 않음. 로그인은 이후에.
|
||||
|
||||
$name = $input['name'];
|
||||
$name = htmlspecialchars($name);
|
||||
$name = StringUtil::removeSpecialCharacter($name);
|
||||
$name = WebUtil::htmlPurify($name);
|
||||
$name = StringUtil::textStrip($name);
|
||||
$pic = $input['pic'];
|
||||
$character = $input['character'];
|
||||
|
||||
$leadership = $input['leadership'];
|
||||
$strength = $input['strength'];
|
||||
$intel = $input['intel'];
|
||||
|
||||
$inheritSpecial = $input['inheritSpecial']??null;
|
||||
$inheritTurntime =$input['inheritTurntime']??null;
|
||||
$inheritCity = $input['inheritCity']??null;
|
||||
$inheritBonusStat = $input['inheritBonusStat']??null;
|
||||
|
||||
$rootDB = RootDB::db();
|
||||
//회원 테이블에서 정보확인
|
||||
$member = $rootDB->queryFirstRow('SELECT `no`, id, picture, grade, `name`, imgsvr FROM member WHERE no=%i', $userID);
|
||||
|
||||
if (!$member) {
|
||||
Json::dieWithReason("잘못된 접근입니다!!!");
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->cacheValues(['year', 'month', 'maxgeneral', 'scenario', 'show_img_level', 'turnterm', 'turntime', 'genius', 'npcmode']);
|
||||
########## 동일 정보 존재여부 확인. ##########
|
||||
|
||||
$gencount = $db->queryFirstField('SELECT count(`no`) FROM general WHERE npc<2');
|
||||
$oldGeneral = $db->queryFirstField('SELECT `no` FROM general WHERE `owner`=%i', $userID);
|
||||
$oldName = $db->queryFirstField('SELECT `no` FROM general WHERE `name`=%s', $name);
|
||||
|
||||
if ($oldGeneral) {
|
||||
Json::dieWithReason("이미 등록하셨습니다!");
|
||||
}
|
||||
if ($oldName) {
|
||||
Json::dieWithReason("이미 있는 장수입니다. 다른 이름으로 등록해 주세요!");
|
||||
}
|
||||
if ($gameStor->maxgeneral <= $gencount) {
|
||||
Json::dieWithReason("더이상 등록할 수 없습니다!");
|
||||
}
|
||||
if ($name == '') {
|
||||
Json::dieWithReason("이름이 짧습니다. 다시 가입해주세요!");
|
||||
}
|
||||
if (mb_strwidth($name) > 18) {
|
||||
Json::dieWithReason("이름이 유효하지 않습니다. 다시 가입해주세요!");
|
||||
}
|
||||
if ($leadership + $strength + $intel > GameConst::$defaultStatTotal) {
|
||||
Json::dieWithReason("능력치가 " . GameConst::$defaultStatTotal . "을 넘어섰습니다. 다시 가입해주세요!");
|
||||
}
|
||||
|
||||
if ($inheritBonusStat) {
|
||||
if (count($inheritBonusStat) != 3) {
|
||||
Json::dieWithReason("보너스 능력치가 잘못 지정되었습니다. 다시 가입해주세요!");
|
||||
}
|
||||
$sum = array_sum($inheritBonusStat);
|
||||
if ($sum < 3 || $sum > 5) {
|
||||
Json::dieWithReason("보너스 능력치 합이 잘못 지정되었습니다. 다시 가입해주세요!");
|
||||
}
|
||||
foreach ($inheritBonusStat as $stat) {
|
||||
if ($stat < 0) {
|
||||
Json::dieWithReason("보너스 능력치가 음수입니다. 다시 가입해주세요!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$admin = $gameStor->getValues(['scenario', 'turnterm', 'turntime', 'show_img_level', 'startyear', 'year']);
|
||||
|
||||
$inheritTotalPoint = resetInheritanceUser($userID);
|
||||
$inheritRequiredPoint = 0;
|
||||
|
||||
if ($inheritCity !== null) {
|
||||
$inheritRequiredPoint += GameConst::$inheritBornCityPoint;
|
||||
}
|
||||
if ($inheritBonusStat !== null) {
|
||||
$inheritRequiredPoint += GameConst::$inheritBornMaxBonusStat;
|
||||
}
|
||||
if ($inheritSpecial !== null) {
|
||||
$inheritRequiredPoint += GameConst::$inheritBornSpecialPoint;
|
||||
}
|
||||
if ($inheritTurntime !== null) {
|
||||
$inheritRequiredPoint += GameConst::$inheritBornTurntimePoint;
|
||||
}
|
||||
|
||||
if ($inheritTotalPoint < $inheritRequiredPoint) {
|
||||
Json::dieWithReason("유산 포인트가 부족합니다. 다시 가입해주세요!");
|
||||
}
|
||||
|
||||
if ($inheritSpecial !== null && $gameStor->genius == 0) {
|
||||
Json::dieWithReason("이미 천재가 모두 나타났습니다. 다시 가입해주세요!");
|
||||
}
|
||||
|
||||
if ($inheritCity !== null && !key_exists($inheritCity, CityConst::all())) {
|
||||
Json::dieWithReason("도시가 잘못 지정되었습니다. 다시 가입해주세요!");
|
||||
}
|
||||
|
||||
if ($inheritSpecial) {
|
||||
$genius = true;
|
||||
} else {
|
||||
// 현재 1%
|
||||
$genius = Util::randBool(0.01);
|
||||
}
|
||||
|
||||
if ($genius && $gameStor->genius > 0) {
|
||||
$gameStor->genius = $gameStor->genius - 1;
|
||||
} else {
|
||||
$genius = false;
|
||||
}
|
||||
|
||||
if ($inheritCity !== null) {
|
||||
$city = $inheritCity;
|
||||
} else {
|
||||
// 공백지에서만 태어나게
|
||||
$city = $db->queryFirstField("select city from city where level>=5 and level<=6 and nation=0 order by rand() limit 0,1");
|
||||
if (!$city) {
|
||||
$city = $db->queryFirstField("select city from city where level>=5 and level<=6 order by rand() limit 0,1");
|
||||
}
|
||||
}
|
||||
|
||||
if ($inheritBonusStat) {
|
||||
[$pleadership, $pstrength, $pintel] = $inheritBonusStat;
|
||||
} else {
|
||||
$pleadership = 0;
|
||||
$pstrength = 0;
|
||||
$pintel = 0;
|
||||
foreach (Util::range(Util::randRangeInt(3, 5)) as $statIdx) {
|
||||
switch (Util::choiceRandomUsingWeight([$leadership, $strength, $intel])) {
|
||||
case 0:
|
||||
$pleadership++;
|
||||
break;
|
||||
case 1:
|
||||
$pstrength++;
|
||||
break;
|
||||
case 2:
|
||||
$pintel++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$leadership = $leadership + $pleadership;
|
||||
$strength = $strength + $pstrength;
|
||||
$intel = $intel + $pintel;
|
||||
|
||||
$relYear = Util::valueFit($admin['year'] - $admin['startyear'], 0);
|
||||
|
||||
$age = 20 + ($pleadership + $pstrength + $pintel) * 2 - (mt_rand(0, 1));
|
||||
// 아직 남았고 천재등록상태이면 특기 부여
|
||||
if ($genius) {
|
||||
$specage2 = $age;
|
||||
if ($inheritSpecial) {
|
||||
$special2 = $inheritSpecial;
|
||||
} else {
|
||||
$special2 = SpecialityHelper::pickSpecialWar([
|
||||
'leadership' => $leadership,
|
||||
'strength' => $strength,
|
||||
'intel' => $intel,
|
||||
'dex1' => 0,
|
||||
'dex2' => 0,
|
||||
'dex3' => 0,
|
||||
'dex4' => 0,
|
||||
'dex5' => 0
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$specage2 = Util::valueFit(Util::round((GameConst::$retirementYear - $age) / 6 - $relYear / 2), 3) + $age;
|
||||
$special2 = GameConst::$defaultSpecialWar;
|
||||
}
|
||||
//내특
|
||||
$specage = Util::valueFit(Util::round((GameConst::$retirementYear - $age) / 12 - $relYear / 2), 3) + $age;
|
||||
$special = GameConst::$defaultSpecialDomestic;
|
||||
|
||||
if ($admin['scenario'] >= 1000) {
|
||||
$specage2 = $age + 3;
|
||||
$specage = $age + 3;
|
||||
}
|
||||
|
||||
if ($relYear < 3) {
|
||||
$experience = 0;
|
||||
} else {
|
||||
$expGenCount = $db->queryFirstField('SELECT count(*) FROM general WHERE nation != 0 AND npc < 4');
|
||||
$targetGenOrder = Util::round($expGenCount * 0.2);
|
||||
$experience = $db->queryFirstField(
|
||||
'SELECT experience FROM general WHERE nation != 0 AND npc < 4 ORDER BY experience ASC LIMIT %i, 1',
|
||||
$targetGenOrder - 1
|
||||
);
|
||||
$experience *= 0.8;
|
||||
}
|
||||
|
||||
if ($inheritTurntime === null) {
|
||||
$inheritTurntime = $inheritTurntime % ($gameStor->turnterm * 60);
|
||||
$inheritTurntime += Util::randRangeInt(0, 999999) / 1000000;
|
||||
$turntime = cutTurn($admin['turntime'], $admin['turnterm']);
|
||||
$turntime = TimeUtil::nowAddSeconds($inheritTurntime, true);
|
||||
} else {
|
||||
$turntime = getRandTurn($admin['turnterm'], new \DateTimeImmutable($admin['turntime']));
|
||||
}
|
||||
|
||||
|
||||
$now = TimeUtil::now(true);
|
||||
if ($now >= $turntime) {
|
||||
$turntime = addTurn($turntime, $admin['turnterm']);
|
||||
}
|
||||
|
||||
//특회 전콘
|
||||
if ($admin['show_img_level'] >= 1 && $member['grade'] >= 1 && $member['picture'] != "" && $pic) {
|
||||
$face = $member['picture'];
|
||||
$imgsvr = $member['imgsvr'];
|
||||
} else {
|
||||
$face = "default.jpg";
|
||||
$imgsvr = 0;
|
||||
}
|
||||
|
||||
//성격 랜덤시
|
||||
if (!in_array($character, GameConst::$availablePersonality)) {
|
||||
$character = Util::choiceRandom(GameConst::$availablePersonality);
|
||||
}
|
||||
//상성 랜덤
|
||||
$affinity = rand() % 150 + 1;
|
||||
|
||||
########## 회원정보 테이블에 입력값을 등록한다. ##########
|
||||
$db->insert('general', [
|
||||
'owner' => $userID,
|
||||
'name' => $name,
|
||||
'owner_name' => $member['name'],
|
||||
'picture' => $face,
|
||||
'imgsvr' => $imgsvr,
|
||||
'nation' => 0,
|
||||
'city' => $city,
|
||||
'troop' => 0,
|
||||
'affinity' => $affinity,
|
||||
'leadership' => $leadership,
|
||||
'strength' => $strength,
|
||||
'intel' => $intel,
|
||||
'experience' => $experience,
|
||||
'dedication' => 0,
|
||||
'gold' => GameConst::$defaultGold,
|
||||
'rice' => GameConst::$defaultRice,
|
||||
'crew' => 0,
|
||||
'train' => 0,
|
||||
'atmos' => 0,
|
||||
'officer_level' => 0,
|
||||
'turntime' => $turntime,
|
||||
'killturn' => 6,
|
||||
'lastconnect' => $now,
|
||||
'lastrefresh' => $now,
|
||||
'crewtype' => GameUnitConst::DEFAULT_CREWTYPE,
|
||||
'makelimit' => 0,
|
||||
'age' => $age,
|
||||
'startage' => $age,
|
||||
'personal' => $character,
|
||||
'specage' => $specage,
|
||||
'special' => $special,
|
||||
'specage2' => $specage2,
|
||||
'special2' => $special2
|
||||
]);
|
||||
$generalID = $db->insertId();
|
||||
$turnRows = [];
|
||||
foreach (Util::range(GameConst::$maxTurn) as $turnIdx) {
|
||||
$turnRows[] = [
|
||||
'general_id' => $generalID,
|
||||
'turn_idx' => $turnIdx,
|
||||
'action' => '휴식',
|
||||
'arg' => null,
|
||||
'brief' => '휴식'
|
||||
];
|
||||
}
|
||||
$db->insert('general_turn', $turnRows);
|
||||
|
||||
$rank_data = [];
|
||||
foreach (array_keys(General::RANK_COLUMN) as $rankColumn) {
|
||||
$rank_data[] = [
|
||||
'general_id' => $generalID,
|
||||
'nation_id' => 0,
|
||||
'type' => $rankColumn,
|
||||
'value' => 0
|
||||
];
|
||||
}
|
||||
$db->insert('rank_data', $rank_data);
|
||||
$db->insert('betting', [
|
||||
'general_id' => $generalID,
|
||||
]);
|
||||
$cityname = CityConst::byID($city)->name;
|
||||
|
||||
$me = [
|
||||
'no' => $generalID
|
||||
];
|
||||
|
||||
$log = [];
|
||||
$mylog = [];
|
||||
|
||||
$logger = new ActionLogger($generalID, 0, $gameStor->year, $gameStor->month);
|
||||
|
||||
$josaRa = JosaUtil::pick($name, '라');
|
||||
$speicalText = getGeneralSpecialWarName($special2);
|
||||
if ($genius) {
|
||||
|
||||
$logger->pushGlobalActionLog("<G><b>{$cityname}</b></>에서 <Y>{$name}</>{$josaRa}는 기재가 천하에 이름을 알립니다.");
|
||||
$logger->pushGlobalActionLog("<C>{$speicalText}</> 특기를 가진 <C>천재</>의 등장으로 온 천하가 떠들썩합니다.");
|
||||
$logger->pushGlobalHistoryLog("<L><b>【천재】</b></><G><b>{$cityname}</b></>에 천재가 등장했습니다.");
|
||||
} else {
|
||||
$logger->pushGlobalActionLog("<G><b>{$cityname}</b></>에서 <Y>{$name}</>{$josaRa}는 호걸이 천하에 이름을 알립니다.");
|
||||
}
|
||||
|
||||
$logger->pushGeneralHistoryLog("<Y>{$name}</>, <G>{$cityname}</>에서 큰 뜻을 품다.");
|
||||
$logger->pushGeneralActionLog("삼국지 모의전투 PHP의 세계에 오신 것을 환영합니다 ^o^", ActionLogger::PLAIN);
|
||||
$logger->pushGeneralActionLog("처음 하시는 경우에는 <D>도움말</>을 참고하시고,", ActionLogger::PLAIN);
|
||||
$logger->pushGeneralActionLog("문의사항이 있으시면 게시판에 글을 남겨주시면 되겠네요~", ActionLogger::PLAIN);
|
||||
$logger->pushGeneralActionLog("부디 즐거운 삼모전 되시길 바랍니다 ^^", ActionLogger::PLAIN);
|
||||
$logger->pushGeneralActionLog("통솔 <C>$pleadership</> 무력 <C>$pstrength</> 지력 <C>$pintel</> 의 보너스를 받으셨습니다.", ActionLogger::PLAIN);
|
||||
$logger->pushGeneralActionLog("연령은 <C>$age</>세로 시작합니다.", ActionLogger::PLAIN);
|
||||
|
||||
if ($genius) {
|
||||
$logger->pushGeneralActionLog("축하합니다! 천재로 태어나 처음부터 <C>{$speicalText}</> 특기를 가지게 됩니다!", ActionLogger::PLAIN);
|
||||
$logger->pushGeneralHistoryLog("<C>{$speicalText}</> 특기를 가진 천재로 탄생.");
|
||||
}
|
||||
|
||||
$logger->flush();
|
||||
|
||||
pushAdminLog(["가입 : {$userID} // {$name} // {$generalID}" . getenv("REMOTE_ADDR")]);
|
||||
|
||||
$rootDB->insert('member_log', [
|
||||
'member_no' => $userID,
|
||||
'date' => TimeUtil::now(),
|
||||
'action_type' => 'make_general',
|
||||
'action' => Json::encode([
|
||||
'server' => DB::prefix(),
|
||||
'type' => 'general',
|
||||
'generalID' => $generalID,
|
||||
'generalName' => $name
|
||||
])
|
||||
]);
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
+37
-12
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
@@ -6,7 +6,7 @@ use sammo\Command\BaseCommand;
|
||||
|
||||
/**
|
||||
* Value Converter
|
||||
*
|
||||
*
|
||||
* Side effect 없이 값의 변환만을 수행하는 함수들의 모음.
|
||||
* (단, autoload, 정적 변수 초기화는 허용)
|
||||
*/
|
||||
@@ -175,7 +175,7 @@ function buildNationTypeClass(?string $type):BaseNation{
|
||||
return $cache[$type];
|
||||
}
|
||||
$class = getNationTypeClass($type);
|
||||
|
||||
|
||||
$obj = new $class();
|
||||
$cache[$type]= $obj;
|
||||
return $obj;
|
||||
@@ -241,7 +241,7 @@ function buildItemClass(?string $type):BaseItem{
|
||||
return $cache[$type];
|
||||
}
|
||||
$class = getItemClass($type);
|
||||
|
||||
|
||||
$obj = new $class();
|
||||
$cache[$type]= $obj;
|
||||
return $obj;
|
||||
@@ -276,7 +276,7 @@ function buildGeneralSpecialDomesticClass(?string $type):BaseSpecial{
|
||||
return $cache[$type];
|
||||
}
|
||||
$class = getGeneralSpecialDomesticClass($type);
|
||||
|
||||
|
||||
$obj = new $class();
|
||||
$cache[$type]= $obj;
|
||||
return $obj;
|
||||
@@ -311,7 +311,7 @@ function buildGeneralSpecialWarClass(?string $type):BaseSpecial{
|
||||
return $cache[$type];
|
||||
}
|
||||
$class = getGeneralSpecialWarClass($type);
|
||||
|
||||
|
||||
$obj = new $class();
|
||||
$cache[$type]= $obj;
|
||||
return $obj;
|
||||
@@ -357,6 +357,31 @@ function buildNationCommandClass(?string $type, General $generalObj, array $env,
|
||||
return new $class($generalObj, $env, $lastTurn, $arg);
|
||||
}
|
||||
|
||||
function getAPIExecutorClass($path){
|
||||
|
||||
static $basePath = __NAMESPACE__.'\\API\\';
|
||||
if(is_string($path)){
|
||||
}
|
||||
else if(is_array($path)){
|
||||
$path = join('\\', $path);
|
||||
}
|
||||
else{
|
||||
throw new \InvalidArgumentException("{$path}는 올바른 API 지시자가 아님");
|
||||
}
|
||||
|
||||
$classPath = ($basePath.$path);
|
||||
|
||||
if(class_exists($classPath)){
|
||||
return $classPath;
|
||||
}
|
||||
throw new \InvalidArgumentException("{$path}는 올바른 API 경로가 아님");
|
||||
}
|
||||
|
||||
function buildAPIExecutorClass(string $type, array $args):\sammo\BaseAPI{
|
||||
$class = getAPIExecutorClass($type);
|
||||
return new $class($args);
|
||||
}
|
||||
|
||||
function getWarUnitTriggerClass(string $type){
|
||||
static $basePath = __NAMESPACE__.'\\WarUnitTrigger\\';
|
||||
$classPath = ($basePath.$type);
|
||||
@@ -391,8 +416,8 @@ function getGeneralPoolClass(string $type){
|
||||
|
||||
/**
|
||||
* @param \MeekroDB $db
|
||||
* @param int $owner
|
||||
* @param int $pickCnt
|
||||
* @param int $owner
|
||||
* @param int $pickCnt
|
||||
* @param null|string $prefix
|
||||
* @return AbsGeneralPool[]
|
||||
*/
|
||||
@@ -538,8 +563,8 @@ function getExpLevel($experience) {
|
||||
|
||||
function getDedLevel($dedication) {
|
||||
$level = Util::valueFit(
|
||||
ceil(sqrt($dedication) / 10),
|
||||
0,
|
||||
ceil(sqrt($dedication) / 10),
|
||||
0,
|
||||
GameConst::$maxDedLevel
|
||||
);
|
||||
|
||||
@@ -572,7 +597,7 @@ function getCost(int $armtype) : int {
|
||||
function getTechLevel($tech):int{
|
||||
return Util::valueFit(
|
||||
floor($tech / 1000),
|
||||
0,
|
||||
0,
|
||||
GameConst::$maxTechLevel
|
||||
);
|
||||
}
|
||||
@@ -583,7 +608,7 @@ function TechLimit($startYear, $year, $tech) : bool {
|
||||
|
||||
$relMaxTech = Util::valueFit(
|
||||
floor($relYear / 5) + 1,
|
||||
1,
|
||||
1,
|
||||
GameConst::$maxTechLevel
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,426 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\General;
|
||||
|
||||
use sammo\ActionLogger;
|
||||
use sammo\CityConst;
|
||||
use sammo\DB;
|
||||
use sammo\GameConst;
|
||||
use sammo\GameUnitConst;
|
||||
use sammo\General;
|
||||
use sammo\JosaUtil;
|
||||
use sammo\Json;
|
||||
use sammo\KVStorage;
|
||||
use sammo\RootDB;
|
||||
use sammo\Session;
|
||||
use sammo\SpecialityHelper;
|
||||
use sammo\StringUtil;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Util;
|
||||
use sammo\Validator;
|
||||
use sammo\WebUtil;
|
||||
|
||||
use function sammo\addTurn;
|
||||
use function sammo\cutTurn;
|
||||
use function sammo\getGeneralSpecialWarName;
|
||||
use function sammo\getRandTurn;
|
||||
use function sammo\pushAdminLog;
|
||||
use function sammo\resetInheritanceUser;
|
||||
|
||||
class Join extends \sammo\BaseAPI
|
||||
{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v
|
||||
->rule('required', [
|
||||
'name',
|
||||
'leadership',
|
||||
'strength',
|
||||
'intel',
|
||||
'pic',
|
||||
'character',
|
||||
])
|
||||
->rule('integer', [
|
||||
'leadership',
|
||||
'strength',
|
||||
'intel',
|
||||
'inheritTurntime',
|
||||
])
|
||||
->rule('boolean', [
|
||||
'pic'
|
||||
])
|
||||
->rule('stringWidthBetween', 'name', 1, 18)
|
||||
->rule('min', [
|
||||
'leadership',
|
||||
'strength',
|
||||
'intel'
|
||||
], GameConst::$defaultStatMin)
|
||||
->rule('max', [
|
||||
'leadership',
|
||||
'strength',
|
||||
'intel'
|
||||
], GameConst::$defaultStatMax)
|
||||
->rule('in', 'character', array_merge(GameConst::$availablePersonality, ['Random']))
|
||||
->rule('in', 'inheritSpecial', GameConst::$availableSpecialWar)
|
||||
->rule('min', 'inheritTurntime', 0)
|
||||
->rule('in', 'inheritCity', array_keys(CityConst::all()))
|
||||
->rule('integerArray', 'inheritBonusStat');
|
||||
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return static::REQ_LOGIN | static::REQ_READ_ONLY;
|
||||
}
|
||||
|
||||
public function launch(?Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
if($session === null){
|
||||
throw "invalid session";
|
||||
}
|
||||
|
||||
$userID = $session->userID;
|
||||
|
||||
$name = $this->args['name'];
|
||||
$name = htmlspecialchars($name);
|
||||
$name = StringUtil::removeSpecialCharacter($name);
|
||||
$name = WebUtil::htmlPurify($name);
|
||||
$name = StringUtil::textStrip($name);
|
||||
$pic = $this->args['pic'];
|
||||
$character = $this->args['character'];
|
||||
|
||||
$leadership = $this->args['leadership'];
|
||||
$strength = $this->args['strength'];
|
||||
$intel = $this->args['intel'];
|
||||
|
||||
$inheritSpecial = $this->args['inheritSpecial']??null;
|
||||
$inheritTurntime =$this->args['inheritTurntime']??null;
|
||||
$inheritCity = $this->args['inheritCity']??null;
|
||||
$inheritBonusStat = $this->args['inheritBonusStat']??null;
|
||||
|
||||
$rootDB = RootDB::db();
|
||||
//회원 테이블에서 정보확인
|
||||
$member = $rootDB->queryFirstRow('SELECT `no`, id, picture, grade, `name`, imgsvr FROM member WHERE no=%i', $userID);
|
||||
|
||||
if (!$member) {
|
||||
return "잘못된 접근입니다!!!";
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->cacheValues(['year', 'month', 'maxgeneral', 'scenario', 'show_img_level', 'turnterm', 'turntime', 'genius', 'npcmode']);
|
||||
########## 동일 정보 존재여부 확인. ##########
|
||||
|
||||
$gencount = $db->queryFirstField('SELECT count(`no`) FROM general WHERE npc<2');
|
||||
$oldGeneral = $db->queryFirstField('SELECT `no` FROM general WHERE `owner`=%i', $userID);
|
||||
$oldName = $db->queryFirstField('SELECT `no` FROM general WHERE `name`=%s', $name);
|
||||
|
||||
if ($oldGeneral) {
|
||||
return "이미 등록하셨습니다!";
|
||||
}
|
||||
if ($oldName) {
|
||||
return "이미 있는 장수입니다. 다른 이름으로 등록해 주세요!";
|
||||
}
|
||||
if ($gameStor->maxgeneral <= $gencount) {
|
||||
return "더이상 등록할 수 없습니다!";
|
||||
}
|
||||
if ($name == '') {
|
||||
return "이름이 짧습니다. 다시 가입해주세요!";
|
||||
}
|
||||
if (mb_strwidth($name) > 18) {
|
||||
return "이름이 유효하지 않습니다. 다시 가입해주세요!";
|
||||
}
|
||||
if ($leadership + $strength + $intel > GameConst::$defaultStatTotal) {
|
||||
return "능력치가 " . GameConst::$defaultStatTotal . "을 넘어섰습니다. 다시 가입해주세요!";
|
||||
}
|
||||
|
||||
if ($inheritBonusStat) {
|
||||
if (count($inheritBonusStat) != 3) {
|
||||
return "보너스 능력치가 잘못 지정되었습니다. 다시 가입해주세요!";
|
||||
}
|
||||
$sum = array_sum($inheritBonusStat);
|
||||
if ($sum < 3 || $sum > 5) {
|
||||
return "보너스 능력치 합이 잘못 지정되었습니다. 다시 가입해주세요!";
|
||||
}
|
||||
foreach ($inheritBonusStat as $stat) {
|
||||
if ($stat < 0) {
|
||||
return "보너스 능력치가 음수입니다. 다시 가입해주세요!";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$admin = $gameStor->getValues(['scenario', 'turnterm', 'turntime', 'show_img_level', 'startyear', 'year']);
|
||||
|
||||
$inheritTotalPoint = resetInheritanceUser($userID);
|
||||
$inheritRequiredPoint = 0;
|
||||
|
||||
if ($inheritCity !== null) {
|
||||
$inheritRequiredPoint += GameConst::$inheritBornCityPoint;
|
||||
}
|
||||
if ($inheritBonusStat !== null) {
|
||||
$inheritRequiredPoint += GameConst::$inheritBornMaxBonusStat;
|
||||
}
|
||||
if ($inheritSpecial !== null) {
|
||||
$inheritRequiredPoint += GameConst::$inheritBornSpecialPoint;
|
||||
}
|
||||
if ($inheritTurntime !== null) {
|
||||
$inheritRequiredPoint += GameConst::$inheritBornTurntimePoint;
|
||||
}
|
||||
|
||||
if ($inheritTotalPoint < $inheritRequiredPoint) {
|
||||
return "유산 포인트가 부족합니다. 다시 가입해주세요!";
|
||||
}
|
||||
|
||||
if ($inheritSpecial !== null && $gameStor->genius == 0) {
|
||||
return "이미 천재가 모두 나타났습니다. 다시 가입해주세요!";
|
||||
}
|
||||
|
||||
if ($inheritCity !== null && !key_exists($inheritCity, CityConst::all())) {
|
||||
return "도시가 잘못 지정되었습니다. 다시 가입해주세요!";
|
||||
}
|
||||
|
||||
if ($inheritSpecial) {
|
||||
$genius = true;
|
||||
} else {
|
||||
// 현재 1%
|
||||
$genius = Util::randBool(0.01);
|
||||
}
|
||||
|
||||
if ($genius && $gameStor->genius > 0) {
|
||||
$gameStor->genius = $gameStor->genius - 1;
|
||||
} else {
|
||||
$genius = false;
|
||||
}
|
||||
|
||||
if ($inheritCity !== null) {
|
||||
$city = $inheritCity;
|
||||
} else {
|
||||
// 공백지에서만 태어나게
|
||||
$city = $db->queryFirstField("select city from city where level>=5 and level<=6 and nation=0 order by rand() limit 0,1");
|
||||
if (!$city) {
|
||||
$city = $db->queryFirstField("select city from city where level>=5 and level<=6 order by rand() limit 0,1");
|
||||
}
|
||||
}
|
||||
|
||||
if ($inheritBonusStat) {
|
||||
[$pleadership, $pstrength, $pintel] = $inheritBonusStat;
|
||||
} else {
|
||||
$pleadership = 0;
|
||||
$pstrength = 0;
|
||||
$pintel = 0;
|
||||
foreach (Util::range(Util::randRangeInt(3, 5)) as $statIdx) {
|
||||
switch (Util::choiceRandomUsingWeight([$leadership, $strength, $intel])) {
|
||||
case 0:
|
||||
$pleadership++;
|
||||
break;
|
||||
case 1:
|
||||
$pstrength++;
|
||||
break;
|
||||
case 2:
|
||||
$pintel++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$leadership = $leadership + $pleadership;
|
||||
$strength = $strength + $pstrength;
|
||||
$intel = $intel + $pintel;
|
||||
|
||||
$relYear = Util::valueFit($admin['year'] - $admin['startyear'], 0);
|
||||
|
||||
$age = 20 + ($pleadership + $pstrength + $pintel) * 2 - (mt_rand(0, 1));
|
||||
// 아직 남았고 천재등록상태이면 특기 부여
|
||||
if ($genius) {
|
||||
$specage2 = $age;
|
||||
if ($inheritSpecial) {
|
||||
$special2 = $inheritSpecial;
|
||||
} else {
|
||||
$special2 = SpecialityHelper::pickSpecialWar([
|
||||
'leadership' => $leadership,
|
||||
'strength' => $strength,
|
||||
'intel' => $intel,
|
||||
'dex1' => 0,
|
||||
'dex2' => 0,
|
||||
'dex3' => 0,
|
||||
'dex4' => 0,
|
||||
'dex5' => 0
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$specage2 = Util::valueFit(Util::round((GameConst::$retirementYear - $age) / 6 - $relYear / 2), 3) + $age;
|
||||
$special2 = GameConst::$defaultSpecialWar;
|
||||
}
|
||||
//내특
|
||||
$specage = Util::valueFit(Util::round((GameConst::$retirementYear - $age) / 12 - $relYear / 2), 3) + $age;
|
||||
$special = GameConst::$defaultSpecialDomestic;
|
||||
|
||||
if ($admin['scenario'] >= 1000) {
|
||||
$specage2 = $age + 3;
|
||||
$specage = $age + 3;
|
||||
}
|
||||
|
||||
if ($relYear < 3) {
|
||||
$experience = 0;
|
||||
} else {
|
||||
$expGenCount = $db->queryFirstField('SELECT count(*) FROM general WHERE nation != 0 AND npc < 4');
|
||||
$targetGenOrder = Util::round($expGenCount * 0.2);
|
||||
$experience = $db->queryFirstField(
|
||||
'SELECT experience FROM general WHERE nation != 0 AND npc < 4 ORDER BY experience ASC LIMIT %i, 1',
|
||||
$targetGenOrder - 1
|
||||
);
|
||||
$experience *= 0.8;
|
||||
}
|
||||
|
||||
if ($inheritTurntime === null) {
|
||||
$inheritTurntime = $inheritTurntime % ($gameStor->turnterm * 60);
|
||||
$inheritTurntime += Util::randRangeInt(0, 999999) / 1000000;
|
||||
$turntime = cutTurn($admin['turntime'], $admin['turnterm']);
|
||||
$turntime = TimeUtil::nowAddSeconds($inheritTurntime, true);
|
||||
} else {
|
||||
$turntime = getRandTurn($admin['turnterm'], new \DateTimeImmutable($admin['turntime']));
|
||||
}
|
||||
|
||||
|
||||
$now = TimeUtil::now(true);
|
||||
if ($now >= $turntime) {
|
||||
$turntime = addTurn($turntime, $admin['turnterm']);
|
||||
}
|
||||
|
||||
//특회 전콘
|
||||
if ($admin['show_img_level'] >= 1 && $member['grade'] >= 1 && $member['picture'] != "" && $pic) {
|
||||
$face = $member['picture'];
|
||||
$imgsvr = $member['imgsvr'];
|
||||
} else {
|
||||
$face = "default.jpg";
|
||||
$imgsvr = 0;
|
||||
}
|
||||
|
||||
//성격 랜덤시
|
||||
if (!in_array($character, GameConst::$availablePersonality)) {
|
||||
$character = Util::choiceRandom(GameConst::$availablePersonality);
|
||||
}
|
||||
//상성 랜덤
|
||||
$affinity = rand() % 150 + 1;
|
||||
|
||||
########## 회원정보 테이블에 입력값을 등록한다. ##########
|
||||
$db->insert('general', [
|
||||
'owner' => $userID,
|
||||
'name' => $name,
|
||||
'owner_name' => $member['name'],
|
||||
'picture' => $face,
|
||||
'imgsvr' => $imgsvr,
|
||||
'nation' => 0,
|
||||
'city' => $city,
|
||||
'troop' => 0,
|
||||
'affinity' => $affinity,
|
||||
'leadership' => $leadership,
|
||||
'strength' => $strength,
|
||||
'intel' => $intel,
|
||||
'experience' => $experience,
|
||||
'dedication' => 0,
|
||||
'gold' => GameConst::$defaultGold,
|
||||
'rice' => GameConst::$defaultRice,
|
||||
'crew' => 0,
|
||||
'train' => 0,
|
||||
'atmos' => 0,
|
||||
'officer_level' => 0,
|
||||
'turntime' => $turntime,
|
||||
'killturn' => 6,
|
||||
'lastconnect' => $now,
|
||||
'lastrefresh' => $now,
|
||||
'crewtype' => GameUnitConst::DEFAULT_CREWTYPE,
|
||||
'makelimit' => 0,
|
||||
'age' => $age,
|
||||
'startage' => $age,
|
||||
'personal' => $character,
|
||||
'specage' => $specage,
|
||||
'special' => $special,
|
||||
'specage2' => $specage2,
|
||||
'special2' => $special2
|
||||
]);
|
||||
$generalID = $db->insertId();
|
||||
$turnRows = [];
|
||||
foreach (Util::range(GameConst::$maxTurn) as $turnIdx) {
|
||||
$turnRows[] = [
|
||||
'general_id' => $generalID,
|
||||
'turn_idx' => $turnIdx,
|
||||
'action' => '휴식',
|
||||
'arg' => null,
|
||||
'brief' => '휴식'
|
||||
];
|
||||
}
|
||||
$db->insert('general_turn', $turnRows);
|
||||
|
||||
$rank_data = [];
|
||||
foreach (array_keys(General::RANK_COLUMN) as $rankColumn) {
|
||||
$rank_data[] = [
|
||||
'general_id' => $generalID,
|
||||
'nation_id' => 0,
|
||||
'type' => $rankColumn,
|
||||
'value' => 0
|
||||
];
|
||||
}
|
||||
$db->insert('rank_data', $rank_data);
|
||||
$db->insert('betting', [
|
||||
'general_id' => $generalID,
|
||||
]);
|
||||
$cityname = CityConst::byID($city)->name;
|
||||
|
||||
$me = [
|
||||
'no' => $generalID
|
||||
];
|
||||
|
||||
$log = [];
|
||||
$mylog = [];
|
||||
|
||||
$logger = new ActionLogger($generalID, 0, $gameStor->year, $gameStor->month);
|
||||
|
||||
$josaRa = JosaUtil::pick($name, '라');
|
||||
$speicalText = getGeneralSpecialWarName($special2);
|
||||
if ($genius) {
|
||||
|
||||
$logger->pushGlobalActionLog("<G><b>{$cityname}</b></>에서 <Y>{$name}</>{$josaRa}는 기재가 천하에 이름을 알립니다.");
|
||||
$logger->pushGlobalActionLog("<C>{$speicalText}</> 특기를 가진 <C>천재</>의 등장으로 온 천하가 떠들썩합니다.");
|
||||
$logger->pushGlobalHistoryLog("<L><b>【천재】</b></><G><b>{$cityname}</b></>에 천재가 등장했습니다.");
|
||||
} else {
|
||||
$logger->pushGlobalActionLog("<G><b>{$cityname}</b></>에서 <Y>{$name}</>{$josaRa}는 호걸이 천하에 이름을 알립니다.");
|
||||
}
|
||||
|
||||
$logger->pushGeneralHistoryLog("<Y>{$name}</>, <G>{$cityname}</>에서 큰 뜻을 품다.");
|
||||
$logger->pushGeneralActionLog("삼국지 모의전투 PHP의 세계에 오신 것을 환영합니다 ^o^", ActionLogger::PLAIN);
|
||||
$logger->pushGeneralActionLog("처음 하시는 경우에는 <D>도움말</>을 참고하시고,", ActionLogger::PLAIN);
|
||||
$logger->pushGeneralActionLog("문의사항이 있으시면 게시판에 글을 남겨주시면 되겠네요~", ActionLogger::PLAIN);
|
||||
$logger->pushGeneralActionLog("부디 즐거운 삼모전 되시길 바랍니다 ^^", ActionLogger::PLAIN);
|
||||
$logger->pushGeneralActionLog("통솔 <C>$pleadership</> 무력 <C>$pstrength</> 지력 <C>$pintel</> 의 보너스를 받으셨습니다.", ActionLogger::PLAIN);
|
||||
$logger->pushGeneralActionLog("연령은 <C>$age</>세로 시작합니다.", ActionLogger::PLAIN);
|
||||
|
||||
if ($genius) {
|
||||
$logger->pushGeneralActionLog("축하합니다! 천재로 태어나 처음부터 <C>{$speicalText}</> 특기를 가지게 됩니다!", ActionLogger::PLAIN);
|
||||
$logger->pushGeneralHistoryLog("<C>{$speicalText}</> 특기를 가진 천재로 탄생.");
|
||||
}
|
||||
|
||||
$logger->flush();
|
||||
|
||||
pushAdminLog(["가입 : {$userID} // {$name} // {$generalID}" . getenv("REMOTE_ADDR")]);
|
||||
|
||||
$rootDB->insert('member_log', [
|
||||
'member_no' => $userID,
|
||||
'date' => TimeUtil::now(),
|
||||
'action_type' => 'make_general',
|
||||
'action' => Json::encode([
|
||||
'server' => DB::prefix(),
|
||||
'type' => 'general',
|
||||
'generalID' => $generalID,
|
||||
'generalName' => $name
|
||||
])
|
||||
]);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
abstract class BaseAPI
|
||||
{
|
||||
const NO_SESSION = 0;
|
||||
const REQ_LOGIN = 1;
|
||||
const REQ_GAME_LOGIN = 2;
|
||||
const REQ_READ_ONLY = 4;
|
||||
|
||||
protected array $args;
|
||||
public function __construct(array $args)
|
||||
{
|
||||
$this->args = $args;
|
||||
}
|
||||
abstract public function getRequiredSessionMode(): int;
|
||||
abstract function validateArgs(): ?string;
|
||||
|
||||
/** @return null|string|array */
|
||||
abstract function launch(?Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag);
|
||||
|
||||
public function tryCache():?string{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,7 @@ class Json
|
||||
die(Json::encode($value, $flag));
|
||||
}
|
||||
|
||||
/** @return never */
|
||||
public static function dieWithReason(string $reason){
|
||||
static::die([
|
||||
'result'=>false,
|
||||
|
||||
+40
-33
@@ -1,6 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
use phpDocumentor\Reflection\Types\Boolean;
|
||||
|
||||
class TimeUtil
|
||||
{
|
||||
|
||||
@@ -43,7 +46,7 @@ class TimeUtil
|
||||
/** @deprecated */
|
||||
public static function DatetimeFromMinute($date, $minute)
|
||||
{
|
||||
return date('Y-m-d H:i:s', strtotime($date) + $minute*60);
|
||||
return date('Y-m-d H:i:s', strtotime($date) + $minute * 60);
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
@@ -76,62 +79,63 @@ class TimeUtil
|
||||
return date('H:i:s', strtotime('00:00:00') + $second);
|
||||
}
|
||||
|
||||
public static function today():string
|
||||
public static function today(): string
|
||||
{
|
||||
$obj = new \DateTime();
|
||||
return $obj->format('Y-m-d');
|
||||
}
|
||||
|
||||
public static function now(bool $withFraction=false):string
|
||||
public static function now(bool $withFraction = false): string
|
||||
{
|
||||
$obj = new \DateTime();
|
||||
if(!$withFraction){
|
||||
if (!$withFraction) {
|
||||
return $obj->format('Y-m-d H:i:s');
|
||||
}
|
||||
return $obj->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
|
||||
public static function nowAddDays($day, bool $withFraction=false):string
|
||||
public static function nowAddDays($day, bool $withFraction = false): string
|
||||
{
|
||||
$obj = new \DateTime();
|
||||
$obj->add(static::secondsToDateInterval($day * 3600 * 24));
|
||||
if(!$withFraction){
|
||||
if (!$withFraction) {
|
||||
return $obj->format('Y-m-d H:i:s');
|
||||
}
|
||||
return $obj->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
|
||||
public static function nowAddHours($hour, bool $withFraction=false):string
|
||||
public static function nowAddHours($hour, bool $withFraction = false): string
|
||||
{
|
||||
$obj = new \DateTime();
|
||||
$obj->add(static::secondsToDateInterval($hour * 3600));
|
||||
if(!$withFraction){
|
||||
if (!$withFraction) {
|
||||
return $obj->format('Y-m-d H:i:s');
|
||||
}
|
||||
return $obj->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
|
||||
public static function nowAddMinutes($minute, bool $withFraction=false):string
|
||||
public static function nowAddMinutes($minute, bool $withFraction = false): string
|
||||
{
|
||||
$obj = new \DateTime();
|
||||
$obj->add(static::secondsToDateInterval($minute * 60));
|
||||
if(!$withFraction){
|
||||
if (!$withFraction) {
|
||||
return $obj->format('Y-m-d H:i:s');
|
||||
}
|
||||
return $obj->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
|
||||
public static function nowAddSeconds($second, bool $withFraction=false):string
|
||||
public static function nowAddSeconds($second, bool $withFraction = false): string
|
||||
{
|
||||
$obj = new \DateTime();
|
||||
$obj->add(static::secondsToDateInterval($second));
|
||||
if(!$withFraction){
|
||||
if (!$withFraction) {
|
||||
return $obj->format('Y-m-d H:i:s');
|
||||
}
|
||||
return $obj->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
|
||||
public static function secondsToDateTime(float $fullSeconds, bool $isDateTimeImmutable=false): \DateTimeInterface{
|
||||
public static function secondsToDateTime(float $fullSeconds, bool $isDateTimeImmutable = false, bool $isUTC = false): \DateTimeInterface
|
||||
{
|
||||
$seconds = floor($fullSeconds);
|
||||
$fraction = $fullSeconds - $seconds;
|
||||
|
||||
@@ -139,70 +143,73 @@ class TimeUtil
|
||||
$interval->s = $seconds;
|
||||
$interval->f = $fraction;
|
||||
|
||||
if($isDateTimeImmutable){
|
||||
$dateTime = new \DateTimeImmutable("@0");
|
||||
if ($isDateTimeImmutable) {
|
||||
$dateTime = new \DateTimeImmutable("@0", $isUTC ? new \DateTimeZone("UTC") : null);
|
||||
return $dateTime->add($interval);
|
||||
}
|
||||
|
||||
$dateTime = new \DateTime("@0");
|
||||
$dateTime = new \DateTime("@0", $isUTC ? new \DateTimeZone("UTC") : null);
|
||||
$dateTime->add($interval);
|
||||
return $dateTime;
|
||||
}
|
||||
|
||||
public static function secondsToDateInterval(float $fullSeconds): \DateInterval{
|
||||
public static function secondsToDateInterval(float $fullSeconds): \DateInterval
|
||||
{
|
||||
$d0 = new \DateTime("@0");
|
||||
|
||||
return $d0->diff(static::secondsToDateTime($fullSeconds, true));
|
||||
}
|
||||
|
||||
public static function DateTimeToSeconds(\DateTimeInterface $dateTime): float{
|
||||
$d0 = new \DateTimeImmutable("@0");
|
||||
public static function DateTimeToSeconds(\DateTimeInterface $dateTime, bool $isUTC = false): float
|
||||
{
|
||||
$d0 = new \DateTimeImmutable("@0", $isUTC ? new \DateTimeZone("UTC") : null);
|
||||
|
||||
return static::DateIntervalToSeconds($d0->diff($dateTime));
|
||||
}
|
||||
|
||||
public static function DateIntervalToSeconds(\DateInterval $interval): float{
|
||||
if($interval->days !== FALSE){
|
||||
public static function DateIntervalToSeconds(\DateInterval $interval): float
|
||||
{
|
||||
if ($interval->days !== FALSE) {
|
||||
$days = $interval->days;
|
||||
}
|
||||
else{
|
||||
if($interval->y != 0){
|
||||
} else {
|
||||
if ($interval->y != 0) {
|
||||
throw new \InvalidArgumentException('Year argument conversion is not supported');
|
||||
}
|
||||
if($interval->m != 0){
|
||||
if ($interval->m != 0) {
|
||||
throw new \InvalidArgumentException('Month argument conversion is not supported');
|
||||
}
|
||||
$days = $interval->d;
|
||||
}
|
||||
|
||||
|
||||
$hours = $days * 24 + $interval->h;
|
||||
$minutes = $hours * 60 + $interval->i;
|
||||
$seconds = $minutes * 60 + $interval->s + $interval->f;
|
||||
|
||||
|
||||
return $seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* $baseYear, $baseMonth 부터 $afterMonth 개월 이내인지. $afterMonth 포함.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public static function IsRangeMonth(int $baseYear, int $baseMonth, int $afterMonth, int $askYear, int $askMonth):bool{
|
||||
if($baseMonth < 1 || $baseMonth > 12){
|
||||
public static function IsRangeMonth(int $baseYear, int $baseMonth, int $afterMonth, int $askYear, int $askMonth): bool
|
||||
{
|
||||
if ($baseMonth < 1 || $baseMonth > 12) {
|
||||
throw new \InvalidArgumentException('개월이 올바르지 않음');
|
||||
}
|
||||
if($askMonth < 1 || $askMonth > 12){
|
||||
if ($askMonth < 1 || $askMonth > 12) {
|
||||
throw new \InvalidArgumentException('개월이 올바르지 않음');
|
||||
}
|
||||
|
||||
$minMonth = $baseYear * 12 + $baseMonth;
|
||||
if($afterMonth < 0){
|
||||
if ($afterMonth < 0) {
|
||||
$maxMonth = $minMonth;
|
||||
$minMonth = $maxMonth - $afterMonth;
|
||||
}
|
||||
|
||||
$maxMonth = $minMonth + $afterMonth;
|
||||
$askMonth = $askYear * 12 + $askMonth;
|
||||
if($askMonth < $minMonth || $maxMonth < $askMonth){
|
||||
if ($askMonth < $minMonth || $maxMonth < $askMonth) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user