From 2404ab204765013f6bfbe0c023aae784a95a3187 Mon Sep 17 00:00:00 2001 From: hide_d Date: Tue, 10 Apr 2018 02:38:36 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=83=88=EB=A1=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwe/func_message.php | 41 ----- hwe/sammo/DiplomacticMessage.php | 28 +++ hwe/sammo/Message.php | 286 +++++++++++++++++++++++++++++++ hwe/sammo/MessageTarget.php | 50 ++++++ hwe/sammo/ScoutMessage.php | 91 ++++++++++ hwe/sql/schema.sql | 1 - 6 files changed, 455 insertions(+), 42 deletions(-) create mode 100644 hwe/sammo/DiplomacticMessage.php create mode 100644 hwe/sammo/Message.php create mode 100644 hwe/sammo/MessageTarget.php create mode 100644 hwe/sammo/ScoutMessage.php diff --git a/hwe/func_message.php b/hwe/func_message.php index 7fe1fb9a..35bbdbe7 100644 --- a/hwe/func_message.php +++ b/hwe/func_message.php @@ -1,47 +1,7 @@ id = $row['id']; - $this->mailbox = $row['mailbox']; - $this->type = $row['type']; - $this->isSender = $row['is_sender'] != 0; - $this->src = $db_message['src']; - - if($this->src['nation'] === null){ - $this->src['nation'] = '재야'; - $this->src['color'] = '#FFFFFF'; - $this->src['nation_id'] = null; - } - - $this->dest = $db_message['dest']; - - if($this->dest['nation'] === null){ - $this->dest['nation'] = '재야'; - $this->dest['color'] = '#FFFFFF'; - $this->dest['nation_id'] = null; - } - - $this->time = $row['time']; - $this->text = $db_message['text']; - $this->option = $db_message['option']; - } -} function getSingleMessage($messageID){ $messageInfo = DB::db()->queryFirstRow('select * from `message` where `id` = %i', $messageID); @@ -135,7 +95,6 @@ function sendRawMessage($msgType, $isSender, $mailbox, $src, $dest, $msg, $date, DB::db()->insert('message', [ 'address' => $dest, 'type' => $msgType, - 'is_sender' => $isSender, 'src' => $src['id'], 'dest' => $dest['id'], 'time' => $date, diff --git a/hwe/sammo/DiplomacticMessage.php b/hwe/sammo/DiplomacticMessage.php new file mode 100644 index 00000000..0a0efca5 --- /dev/null +++ b/hwe/sammo/DiplomacticMessage.php @@ -0,0 +1,28 @@ +msgType = $msgType; + $this->src = $src; + $this->dest = $dest; + $this->msg = $msg; + $this->date = $date; + $this->validUntil = $validUntil; + $this->msgOption = $msgOption; + } + + public function setSentInfo(int $mailbox, int $messageID) : this + { + if(!Message::isValidMailBox($mailbox)){ + throw new \InvalidArgumentException('올바르지 않은 mailbox'); + } + + do{ + if($mailbox === Message::MAILBOX_PUBLIC){ + if($this->msgType !== Message::MSGTYPE_PUBLIC){ + throw new \InvalidArgumentException('올바르지 않은 mailbox, msgType !== MSGTYPE_PUBLIC'); + } + $this->isInboxMail = true; + break; + } + if($mailbox > Message::MAILBOX_NATIONAL){ + if($this->msgType === Message::MSGTYPE_DIPLOMACY){ + $this->isInboxMail = true; + break; + } + if ($this->msgType !== Message::MSGTYPE_NATIONAL) { + throw new \InvalidArgumentException('올바르지 않은 mailbox, msgType not in (MSGTYPE_DIPLOMACY, MSGTYPE_NATIONAL)'); + } + if($this->dest->nationID + Message::MAILBOX_NATIONAL === $mailbox){ + $this->isInboxMail = true; + break; + } + if($this->src->nationID + Message::MAILBOX_NATIONAL === $mailbox){ + $this->isInboxMail = false; + break; + } + throw new \InvalidArgumentException('송신, 수신국 둘 중의 어느 메일함도 아닙니다'); + } + if($this->msgType !== Message::MSGTYPE_PRIVATE){ + throw new \InvalidArgumentException('올바르지 않은 mailbox, msgType !== MSGTYPE_PRIVATE'); + } + if($this->dest->generalID === $mailbox){ + $this->isInboxMail = true; + break; + } + if($this->src->generalID === $mailbox){ + $this->isInboxMail = false; + break; + } + throw new \InvalidArgumentException('송신자, 수신자 둘 중의 어느 메일함도 아닙니다'); + }while(false); + + $this->id = $messageID; + $this->mailbox = $mailbox; + return $this; + } + + public static function buildFromArray(array $row) : Message + { + $dbMessage = Json::decode($row['message']); + + $msgType = $row['type']; + $src = MessageTarget::buildFromArray($dbMessage['src']); + $dest = MessageTarget::buildFromArray($dbMessage['dest']); + $option = Util::array_get($dbMessage['option'], []); + + $args = [ + $msgType, + $src, + $dest, + $dbMessage['text'], + new \DateTime($row['time']), + new \DateTime($row['valid_until']), + $option + ]; + + $action = Util::array_get($option['action'], null); + if($msgType === self::MSGTYPE_DIPLOMACY){ + $objMessage = new DiplomacticMessage(...$args); + } + else if($action === 'scout'){ + $objMessage = new ScoutMessage(...$args); + } + else{ + $objMessage = new Message(...$args); + } + + $objMessage->setSentInfo($row['mailbox'], $row['id']); + + return $objMessage; + } + + public static function getMessageByID(int $messageID) : Message + { + $db = DB::db(); + $row = $db->queryFirstRow('SELECT * FROM `message` WHERE `id` = %i', $messageID); + if (!$row) { + return null; + } + return static::buildFromArray($row); + } + + protected static function isValidMailBox(int $mailbox): bool + { + if ($mailbox > self::MAILBOX_PUBLIC) { + return false; + } + if ($mailbox == self::MAILBOX_NATIONAL) { + return false; + } + if ($mailbox <= 0) { + return false; + } + return true; + } + + protected static function isValidMsgType(string $msgType): bool + { + switch ($msgType) { + case static::MSGTYPE_PUBLIC: return true; + case static::MSGTYPE_PRIVATE: return true; + case static::MSGTYPE_NATIONAL: return true; + case static::MSGTYPE_DIPLOMACY: return true; + } + return false; + } + + /** + * @param int $mailbox 메일 사서함. + * @param string $msgType 메일 타입. MSGTYPE 중 하나. + * @param int $limit 가져오고자 하는 수. 0 이하의 값이면 모두. + * @param int $fromSeq 가져오고자 하는 위치. $fromSeq보다 '큰' seq만 가져온다. 따라서 0 이하이면 모두 가져옴. + * @return Message[] + */ + protected static function getRawMessage(int $mailbox, string $msgType, int $limit=30, int $fromSeq = 0) + { + $db = DB::db(); + + if (!static::isValidMsgType($msgType)) { + throw new \InvalidArgumentException('올바르지 않은 $msgType'); + } + + $where = new \WhereClause('and'); + $where->add('mailbox = %i', $mailbox); + $where->add('type = %s', $msgType); + if ($fromSeq > 0) { + $where->add('id > %i', $fromSeq); + } + + if ($limit > 0) { + $limitSql = $db->sqleval('LIMIT %i', $limit); + } else { + $limitSql = new \MeekroDBEval(''); + } + + return array_map(function ($row) { + return static::buildFromArray($row); + }, $db->query('SELECT * FROM `message` WHERE %l %?', $where, $limitSql)); + } + + protected function sendRaw(int $mailbox){ + //NOTE:: 여기선 검증하지 않는다. + + + if($mailbox === self::MAILBOX_PUBLIC){ + $src_id = $this->src->generalID; + $dest_id = self::MAILBOX_PUBLIC; + } + else if($mailbox > self::MAILBOX_NATIONAL){ + $src_id = $this->src->nationID + self::MAILBOX_NATIONAL; + $dest_id = $this->dest->nationID + self::MAILBOX_NATIONAL; + } + else{ + $src_id = $this->src->generalID; + $dest_id = $this->dest->generalID; + } + + + $db = DB::db(); + $db->insert('message', [ + 'address' => $mailbox, + 'type' => $this->msgType, + 'src' => $src_id, + 'dest' => $dest_id, + 'time' => $this->date->format('Y-m-d H:i:s'), + 'valid_until' => $this->validUntil->format('Y-m-d H:i:s'), + 'message' => Json::encode([ + 'src' => $this->src->toArray(), + 'dest' =>$this->dest->toArray(), + 'text' => $this->msg, + 'option' => $this->msgOption + ]) + ]); + return $db->insertId(); + } + + protected function sendToSender() : int{ + if($this->sendCnt > 0){ + throw new \RuntimeException('이미 전송한 메일입니다.'); + } + if($this->msgType === self::MSGTYPE_PRIVATE){ + return $this->sendRaw($this->src->generalID); + } + if($this->msgType === self::MSGTYPE_NATIONAL && $this->src->nationID !== $this->dest->nationID){ + return $this->sendRaw($this->src->nationID + self::MAILBOX_NATIONAL); + } + return 0; + } + + protected function sendToReceiver() : int{ + if($this->sendCnt > 1 || $this->isInboxMail){ + throw new \RuntimeException('이미 전송한 메일입니다.'); + } + + if($this->msgType === self::MSGTYPE_PRIVATE){ + return $this->sendRaw($this->dest->generalID); + } + + if($this->msgType === self::MSGTYPE_NATIONAL || $this->msgType === self::MSGTYPE_DIPLOMACY){ + return $this->sendRaw($this->dest->nationID + self::MAILBOX_NATIONAL); + } + + if($this->msgType === self::MSGTYPE_PUBLIC){ + return $this->sendRaw(self::MAILBOX_PUBLIC); + } + + throw new \RuntimeException('이곳에 올 수 없습니다.'); + } + + public function send(){ + $sendID = $this->sendToSender(); + if($sendID){ + $this->msgOption['relatedMessageID'] = $sendID; + } + $this->sendToReceiver(); + } +} diff --git a/hwe/sammo/MessageTarget.php b/hwe/sammo/MessageTarget.php new file mode 100644 index 00000000..b8860c34 --- /dev/null +++ b/hwe/sammo/MessageTarget.php @@ -0,0 +1,50 @@ + Message::MAILBOX_NATIONAL){ + $this->isGeneral = false; + } + else{ + $this->isGeneral = true; + } + + $this->generalID = $generalID; + $this->nationID = $nationID; + $this->nationName = $nationName; + $this->color = $color; + } + + public static function buildFromArray(array $arr) : MessageTarget + { + if(!Util::array_get($arr['nation'])){ + $arr['nation'] = '재야'; + $arr['color'] = '#ffffff'; + $arr['nation_id'] = 0; + } + + return new MessageTarget($arr['id'], $arr['nation_id'], $arr['nation'], $arr['color']); + } + + public function toArray() : array{ + return [ + 'id'=>$this->generalID, + 'nation_id'=>$this->nationID, + 'nation'=>$this->nationName, + 'color'=>$this->color + ]; + } +} \ No newline at end of file diff --git a/hwe/sammo/ScoutMessage.php b/hwe/sammo/ScoutMessage.php new file mode 100644 index 00000000..7295f422 --- /dev/null +++ b/hwe/sammo/ScoutMessage.php @@ -0,0 +1,91 @@ +queryFirstRow('SELECT nation FROM nation WHERE `no`=%i', $srcGeneralID); + $destGeneral = $db->queryFirstRow('SELECT nation, `level` FROM nation WHERE `no`=%i', $destGeneralID); + if($date === null){ + $date = new DateTime(); + } + + if($destGeneral['level'] == 12){ + if($reason !== null){ + $reason = '군주에게 등용장을 보낼 수 없습니다'; + } + return null; + } + + if(!$srcGeneral['nation']){ + if($reason !== null){ + $reason = '재야 상태일 때에는 등용장을 보낼 수 없습니다'; + } + return null; + } + + if($srcGeneral['nation'] === $destGeneral['nation']){ + if($reason !== null){ + $reason = '같은 소속의 장수에게 등용장을 보낼 수 없습니다'; + } + return null; + } + + $srcNationInfo = getNationStaticInfo($srcGeneral['nation']); + $destNationInfo = getNationStaticInfo($destGeneral['nation']); + + $src = new MessageTarget( + $srcGeneralID, + $srcGeneral['nation'], + $srcNationInfo['name'], + $srcNationInfo['color'] + ); + + $dest = new MessageTarget( + $destGeneralID, + $destGeneral['nation'], + Util::array_get($srcNationInfo['name'], ''), + Util::array_get($srcNationInfo['color'], '') + ); + + $msg = "{$src->nationName}(으)로 망명 권유 서신"; + $validUntil = new \DateTime("9999-12-31 12:59:59"); + + $msgOption = [ + 'action'=>'scout' + ]; + + return new ScoutMessage(Message::MSGTYPE_PRIVATE, $src, $dest, $msg, $date, $validUntil, $msgOption); + } + + public function send(){ + $this->sendToReceiver(); + } + +} \ No newline at end of file diff --git a/hwe/sql/schema.sql b/hwe/sql/schema.sql index 1c53da16..a18094c1 100644 --- a/hwe/sql/schema.sql +++ b/hwe/sql/schema.sql @@ -422,7 +422,6 @@ CREATE TABLE `message` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `mailbox` INT(11) NOT NULL COMMENT '9999 == public, >= 9000 national', `type` ENUM('private','national','public','diplomacy') NOT NULL, - `is_sender` BIT(1) NOT NULL, `src` INT(11) NOT NULL, `dest` INT(11) NOT NULL, `time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,