pid = $pid; $this->model = PlayerModel::find($pid); } else { $this->player_name = $player_name; $this->model = PlayerModel::where('player_name', $player_name)->first(); } if ($this->model) { $this->pid = $this->model->pid; $this->player_name = $this->model->player_name; $this->owner = new User($this->model->uid); $this->is_registered = true; $this->is_banned = ($this->owner->getPermission() == "-1"); } } /** * Get textures of player * * @param string $type steve|alex|cape, 'skin' for texture of preferred model * @return string sha256-hash of texture file */ public function getTexture($type) { if ($type == "skin") $type = ($this->getPreference() == "default") ? "steve" : "alex"; if ($type == "steve" | $type == "alex" | $type == "cape") { $tid = $this->model['tid_'.$type]; return Texture::find($tid)['hash']; } return false; } public function setTexture(Array $tids) { $map = ['steve', 'alex', 'cape']; foreach ($map as $model) { $property = "tid_$model"; if (isset($tids[$property])) { $this->model->$property = $tids[$property]; } } $this->model->last_modified = Utils::getTimeFormatted(); $this->model->save(); return Event::fire(new PlayerProfileUpdated($this)); } public function clearTexture() { $this->setPreference('default'); $this->setTexture(['tid_steve' => 0, 'tid_alex' => 0, 'tid_cape' => 0]); } public function getBinaryTexture($type) { if ($this->getTexture($type) != "") { $hash = $this->getTexture($type); $path = BASE_DIR."/storage/textures/".$hash; if (Storage::disk('textures')->has($hash)) { // Cache friendly return Response::png(Storage::disk('textures')->get($hash), 200, [ 'Last-Modified' => $this->getLastModified(), 'Accept-Ranges' => 'bytes', 'Content-Length' => Storage::disk('textures')->size($hash), ]); } else { abort(404, '请求的贴图已被删除。'); } } else { abort(404, '该用户尚未上传请求的贴图类型 '.$type); } } /** * Set preferred model. * * @param string $type 'slim' or 'default' */ public function setPreference($type) { $this->model->update([ 'preference' => $type, 'last_modified' => Utils::getTimeFormatted() ]); return Event::fire(new PlayerProfileUpdated($this)); } public function getPreference() { return $this->model['preference']; } /** * Register a new player. * * @param User $owner Owner of the player. * @return void */ public function register(User $owner) { $this->owner = $owner; $player = new PlayerModel(); $player->uid = $this->owner->uid; $player->player_name = $this->player_name; $player->preference = "default"; $player->last_modified = Utils::getTimeFormatted(); $player->save(); Event::fire(new PlayerWasAdded($player)); $this->owner->setScore(option('score_per_player'), 'minus'); } /** * Rename the player. * * @param string $new_name * @return mixed */ public function rename($new_name) { $this->model->update([ 'player_name' => $new_name, 'last_modified' => Utils::getTimeFormatted() ]); $this->player_name = $new_name; return Event::fire(new PlayerProfileUpdated($this)); } /** * Set a new owner for the player. * * @param int $uid */ public function setOwner($uid) { $this->model->update(['uid' => $uid]); return Event::fire(new PlayerProfileUpdated($this)); } /** * Get JSON profile * * @param int $api_type Which API to use, 0 for CustomSkinAPI, 1 for UniSkinAPI * @return string User profile in json format */ public function getJsonProfile($api_type) { // Support both CustomSkinLoader API & UniSkinAPI if ($api_type == self::CSL_API || $api_type == self::USM_API) { $responses = Event::fire(new GetPlayerJson($this, $api_type)); // if listeners return nothing if (isset($responses[0]) && $responses[0] !== null) { return $responses[0]; } else { return $this->generateJsonProfile($api_type); } } else { throw new PrettyPageException('不支持的 API_TYPE。', -1); } } /** * Generate player profile in json string * * @param int $api_type * @return string */ public function generateJsonProfile($api_type) { $json[($api_type == self::CSL_API) ? 'username' : 'player_name'] = $this->player_name; $model = $this->getPreference(); $sec_model = ($model == 'default') ? 'slim' : 'default'; if ($api_type == self::USM_API) { $json['last_update'] = $this->getLastModified(); $json['model_preference'] = [$model, $sec_model]; } if ($this->getTexture('steve') || $this->getTexture('alex')) { // Skins dict order by preference model $json['skins'][$model] = $this->getTexture($model == "default" ? "steve" : "alex"); $json['skins'][$sec_model] = $this->getTexture($sec_model == "default" ? "steve" : "alex"); } $json['cape'] = $this->getTexture('cape'); return json_encode($json, JSON_PRETTY_PRINT); } public function updateLastModified() { // @see http://stackoverflow.com/questions/2215354/php-date-format-when-inserting-into-datetime-in-mysql $this->model->update(['last_modified' => Utils::getTimeFormatted()]); return Event::fire(new PlayerProfileUpdated($this)); } /** * Get last modified time * @return timestamp */ public function getLastModified() { return strtotime($this->model['last_modified']); } public function delete() { // Event::fire(new PlayerWasDeleted($this)); return $this->model->delete(); } } class PlayerModel extends \Illuminate\Database\Eloquent\Model { public $primaryKey = 'pid'; protected $table = 'players'; public $timestamps = false; protected $fillable = ['uid', 'player_name', 'preference', 'last_modified']; public function scopeLike($query, $field, $value) { return $query->where($field, 'LIKE', "%$value%"); } }