Rimmer
Помогаю новичкам / Переводчик / Тестер / Заказчик
- Сообщения
- 1,368
- Реакции
- 753
- Автор ресурса
- #81
А что не так? -1 значит выполненоПосмотреть вложение 104929
как это поправить?
А что не так? -1 значит выполненоПосмотреть вложение 104929
как это поправить?
то что он выполнил 6 заданийА что не так? -1 значит выполнено
А вы сбрасывали базу в новом обновлении?то что он выполнил 6 заданий Посмотреть вложение 104936
в бд при этом -1 всего два задания
Режим стоит "continue" "0"
и 331 килов. у него было до этого бага около 2к килов и 4 достижения
Посмотреть вложение 104937
зеленое норм
красное баг
чтобы получить 6 достижений надо намного больше килов
Я понимаю все в бд должно быть как у чела с никрм корвус. Достижение получил в столбце - 1 без сброса очков.
А на скрин какая-то жесть)
Записал"condition" "headshot;weapon = glock"
конечноА вы сбрасывали базу в новом обновлении?
Сообщения автоматически склеены:
Записал
![]()
У меня база работает идеально. Может вы меняли настройки в файле achievements.txt после сброса бд? Тогда такое может бытьконечно
на новой базе все. подправил названия достижений добавив в место пробела _ и все
у меня ина старой версии тож самое было до релиза которая. могу дропнуть еще раз бд. всеравно в этой базе 80% все криво занесено
Посмотреть вложение 104974
чистая потестирую еще
Нет все настроено было, есть вариант сбросил бд в момент когда сервер ещё был включён, слишком быстро все сделал просто в момент перезагрузки сервера . Вчера отключил сервер, очистил бдУ меня база работает идеально. Может вы меняли настройки в файле achievements.txt после сброса бд? Тогда такое может быть
У тебя вроде версия стараяНе заносит данные в базу и заспамило лог файл
L 11/28/2022 - 13:03:36: [SM] [55] Line 156, d:\Hentai\GitHub\Achievements-Reborn\addons\sourcemod\scripting\achievements.sp::Achievements_OnCoreLoaded
L 11/28/2022 - 13:03:36: [SM] [57] Call_Finish
Для сохранение данных о том сколько раз игрок выполнил условие или же -1 если он полностью выполнил ачивкуА для чего под каждую ачивку заводить колонку?
Не слишком ли много будет она занимать если администратор создаст по 50 ачивок и на сервер зайдет 1000 человек, то уже будет не весело 50000 строк, при этом надо ведь при каждом заходе игрока искать их.@Pisex, я об этом и говорю.
Чем она не устроила-то?
Ну, хорошо, давай посчитаем.Не слишком ли много будет она занимать если администратор создаст по 50 ачивок и на сервер зайдет 1000 человек, то уже будет не весело 50000 строк
32 + 8 + 128 + 8 + 4
- 180 байт. Теперь умножаем это число на 50000 - получаем 9000000 байт, или ~9 килобайт.Джоины разрулят, главное индексы грамотно развесить. Тогда будет +- та же скорость, что и от одной таблицы.при этом надо ведь при каждом заходе игрока искать их
В таком варианте веб определенно неудобно будет делать, потому что в текущем мире очень любят через ORM работать с базой. ORM требует заранее объявлять структуру таблицы как-то программно. В той же Symfony это должны быть прямо отдельные классы с руками прописанными property и описанными типами.Да и просили переделать чтобы веб чтобы удобнее было сделать, хз зачем
builds.kruzya.me
. В этой энтити представлена одна единица готовой сборки плагина под какую-то версию SM, и, возможно, с какими-то доп параметрами компиляции (наличие отладки, например).<?php
namespace App\Entity;
use App\Repository\ArtifactRepository;
use App\Util;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=ArtifactRepository::class)
*/
class Artifact extends AbstractEntity
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity=Product::class, inversedBy="artifacts")
* @ORM\JoinColumn(nullable=false)
*/
private $product_id;
/**
* @ORM\Column(type="datetime")
*/
private $uploaded_at;
/**
* @ORM\ManyToMany(targetEntity=Tag::class)
*/
private $tags;
/**
* @ORM\Column(type="string", length=40)
*/
private $file_hash;
/**
* @ORM\Column(type="integer")
*/
private $file_size;
/**
* @ORM\Column(type="string", length=255)
*/
private $file_name;
public function __construct()
{
$this->tags = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getProductId(): ?Product
{
return $this->product_id;
}
public function setProductId(?Product $product_id): self
{
$this->product_id = $product_id;
return $this;
}
public function getUploadedAt(): ?\DateTimeInterface
{
return $this->uploaded_at;
}
public function setUploadedAt(\DateTimeInterface $uploaded_at): self
{
$this->uploaded_at = $uploaded_at;
return $this;
}
/**
* @return Collection|Tag[]
*/
public function getTags(): Collection
{
return $this->tags;
}
public function addTag(Tag $tag): self
{
if (!$this->tags->contains($tag)) {
$this->tags[] = $tag;
}
return $this;
}
public function removeTag(Tag $tag): self
{
$this->tags->removeElement($tag);
return $this;
}
public function getFileHash(): ?string
{
return $this->file_hash;
}
public function setFileHash(string $file_hash): self
{
$this->file_hash = $file_hash;
return $this;
}
public function getFileSize(): ?int
{
return $this->file_size;
}
public function setFileSize(int $file_size): self
{
$this->file_size = $file_size;
return $this;
}
public function getFileName(): ?string
{
return $this->file_name;
}
public function setFileName(string $file_name): self
{
$this->file_name = $file_name;
return $this;
}
public function getPublicPath(): string
{
if (!$this->getId())
{
return '';
}
$id = $this->getId();
$groupId = ($id - ($id % 1000)) / 1000;
return sprintf('artifacts/%s/%d-%s.bin', dechex($groupId), $id, $this->getFileHash());
}
protected function getSerializeData($serializeLevel)
{
$data = [
'id' => $this->getId(),
'product' => $this->getProductId()->jsonSerialize(self::API_MIN), // чтобы избежать рекурсии (в теле продукта на API_DEFAULT включаются и артифакты)
'uploaded_at' => Util::serializeDate($this->getUploadedAt()),
'url' => $this->getPublicPath()
];
if ($serializeLevel >= self::API_DEFAULT)
{
$data['file_hash'] = $this->getFileHash();
$data['file_name'] = $this->getFileName();
$data['file_size'] = $this->getFileSize();
$data['tags'] = $this->getTags()->toArray();
}
return $data;
}
}
В чём его удобство заключается?Да и разве такой способ не более удобен и оптимизирован?
Кто-то мне говорил что так будет удобнее, точно не могу сказать, говорили что для веба будет тоже нормально т.к столбцы можно получить с помощью information_schemaНу, хорошо, давай посчитаем.
50 ачивок, предположим длина ключа каждой -- 128 байт (не помню, сколько допустимая была в том плагине). Значение -- обычный инт (4 байта).
Плюс храним идентификатор юзера (предположим Community ID, да ещё и самым всратым способом -- строкой), 32 байта.
К каждому строковому типу обычно ещё прилагается её длина. Сколько там мускул накидывает для её хранения - не в курсе, но предположим, что 8 байт (64-битное число). Строковых типов у нас два (комьюнити ид и имя ачивки).
Т.е. в максимально худших условиях получим, что одна строка занимает32 + 8 + 128 + 8 + 4
- 180 байт. Теперь умножаем это число на 50000 - получаем 9000000 байт, или ~9 килобайт.
Это действительно много, когда даже на фришном тарифе Арены выделяется 1гб диска?
Джоины разрулят, главное индексы грамотно развесить. Тогда будет +- та же скорость, что и от одной таблицы.
В таком варианте веб определенно неудобно будет делать, потому что в текущем мире очень любят через ORM работать с базой. ORM требует заранее объявлять структуру таблицы как-то программно. В той же Symfony это должны быть прямо отдельные классы с руками прописанными property и описанными типами.
Как думаете, получится ли у Вас для Симфы намутить универсальную энтитю без кодогенерации? Сомневаюсь.
Я его позаимствовал с кодовой базыbuilds.kruzya.me
. В этой энтити представлена одна единица готовой сборки плагина под какую-то версию SM, и, возможно, с какими-то доп параметрами компиляции (наличие отладки, например).
PHP:<?php namespace App\Entity; use App\Repository\ArtifactRepository; use App\Util; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity(repositoryClass=ArtifactRepository::class) */ class Artifact extends AbstractEntity { /** * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") */ private $id; /** * @ORM\ManyToOne(targetEntity=Product::class, inversedBy="artifacts") * @ORM\JoinColumn(nullable=false) */ private $product_id; /** * @ORM\Column(type="datetime") */ private $uploaded_at; /** * @ORM\ManyToMany(targetEntity=Tag::class) */ private $tags; /** * @ORM\Column(type="string", length=40) */ private $file_hash; /** * @ORM\Column(type="integer") */ private $file_size; /** * @ORM\Column(type="string", length=255) */ private $file_name; public function __construct() { $this->tags = new ArrayCollection(); } public function getId(): ?int { return $this->id; } public function getProductId(): ?Product { return $this->product_id; } public function setProductId(?Product $product_id): self { $this->product_id = $product_id; return $this; } public function getUploadedAt(): ?\DateTimeInterface { return $this->uploaded_at; } public function setUploadedAt(\DateTimeInterface $uploaded_at): self { $this->uploaded_at = $uploaded_at; return $this; } /** * @return Collection|Tag[] */ public function getTags(): Collection { return $this->tags; } public function addTag(Tag $tag): self { if (!$this->tags->contains($tag)) { $this->tags[] = $tag; } return $this; } public function removeTag(Tag $tag): self { $this->tags->removeElement($tag); return $this; } public function getFileHash(): ?string { return $this->file_hash; } public function setFileHash(string $file_hash): self { $this->file_hash = $file_hash; return $this; } public function getFileSize(): ?int { return $this->file_size; } public function setFileSize(int $file_size): self { $this->file_size = $file_size; return $this; } public function getFileName(): ?string { return $this->file_name; } public function setFileName(string $file_name): self { $this->file_name = $file_name; return $this; } public function getPublicPath(): string { if (!$this->getId()) { return ''; } $id = $this->getId(); $groupId = ($id - ($id % 1000)) / 1000; return sprintf('artifacts/%s/%d-%s.bin', dechex($groupId), $id, $this->getFileHash()); } protected function getSerializeData($serializeLevel) { $data = [ 'id' => $this->getId(), 'product' => $this->getProductId()->jsonSerialize(self::API_MIN), // чтобы избежать рекурсии (в теле продукта на API_DEFAULT включаются и артифакты) 'uploaded_at' => Util::serializeDate($this->getUploadedAt()), 'url' => $this->getPublicPath() ]; if ($serializeLevel >= self::API_DEFAULT) { $data['file_hash'] = $this->getFileHash(); $data['file_name'] = $this->getFileName(); $data['file_size'] = $this->getFileSize(); $data['tags'] = $this->getTags()->toArray(); } return $data; } }
Ну и ещё пример энтити на C# для дефолтной там ORM - Entity Framework: ModularTelegramBot
В чём его удобство заключается?
Ну, если не юзать ORM, и писать сырые запросы к базе, то да, нормально.говорили что для веба будет тоже нормально т.к столбцы можно получить с помощью information_schema
DESCRIBE
: