属性读取ok
This commit is contained in:
parent
44deb18e2c
commit
1e4322e36e
@ -25,9 +25,13 @@ Android::~Android()
|
||||
void Android::Initialize()
|
||||
{
|
||||
Human::Initialize();
|
||||
health = meta->i->health();
|
||||
SetSkinInfo(14001);
|
||||
SetSkinInfo(15001);
|
||||
GiveEquip();
|
||||
skin_meta = MetaMgr::Instance()->GetTank(SkinId());
|
||||
if (skin_meta) {
|
||||
skill_meta = MetaMgr::Instance()->GetSkill(skin_meta->i->skill_id());
|
||||
}
|
||||
RecalcBaseAttr();
|
||||
}
|
||||
|
||||
void Android::Update(int delta_time)
|
||||
|
@ -61,7 +61,7 @@ void Bullet::OnHit(std::set<Entity*>& objects)
|
||||
(hum->team_id == 0 || player->team_id != hum->team_id)) {
|
||||
#endif
|
||||
float dmg = meta->i->atk() * (1 + player->ability.damage_add);
|
||||
float def = hum->def + hum->ability.def_add;
|
||||
float def = hum->ability.def + hum->ability.def_add;
|
||||
float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K);
|
||||
player->stats.damage_amount_out += finaly_dmg;
|
||||
if (!hum->HasBuffEffect(BET_Invincible)) {
|
||||
|
@ -73,15 +73,16 @@ float Human::GetSpeed()
|
||||
{
|
||||
float speed = 0.0f;
|
||||
if (downed) {
|
||||
speed = meta->i->move_speed3() + ability.speed;
|
||||
//倒地速度
|
||||
speed = ability.speed;
|
||||
} else {
|
||||
speed = meta->i->move_speed() + ability.speed;
|
||||
if (shot_hold) {
|
||||
speed = ability.speed;
|
||||
if (action_type == AT_Reload) {
|
||||
speed = ability.reload_speed;
|
||||
} else if (shot_hold) {
|
||||
if (curr_weapon->weapon_idx == GUN_SLOT1 ||
|
||||
curr_weapon->weapon_idx == GUN_SLOT2) {
|
||||
if (action_type != AT_Reload) {
|
||||
speed = meta->i->shot_speed();
|
||||
}
|
||||
speed = ability.shot_speed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -91,7 +92,7 @@ float Human::GetSpeed()
|
||||
|
||||
float Human::GetSpeed4()
|
||||
{
|
||||
return meta->i->move_speed4();
|
||||
return ability.speed;
|
||||
}
|
||||
|
||||
void Human::FillMFObjectPart(cs::MFObjectPart* part_data)
|
||||
@ -101,7 +102,7 @@ void Human::FillMFObjectPart(cs::MFObjectPart* part_data)
|
||||
p->set_obj_uniid(entity_uniid);
|
||||
TypeConvert::ToPb(pos, p->mutable_pos());
|
||||
TypeConvert::ToPb(attack_dir, p->mutable_dir());
|
||||
p->set_health(health);
|
||||
p->set_health(GetHP());
|
||||
p->set_max_health(GetMaxHP());
|
||||
}
|
||||
|
||||
@ -113,7 +114,7 @@ void Human::FillMFObjectFull(cs::MFObjectFull* full_data)
|
||||
TypeConvert::ToPb(pos, p->mutable_pos());
|
||||
TypeConvert::ToPb(attack_dir, p->mutable_dir());
|
||||
|
||||
p->set_health(health);
|
||||
p->set_health(GetHP());
|
||||
p->set_max_health(GetMaxHP());
|
||||
p->set_dead(dead);
|
||||
p->set_downed(downed);
|
||||
@ -185,7 +186,7 @@ void Human::FillMFTeamData(cs::MFTeamData* team_data)
|
||||
team_data->set_name(name);
|
||||
TypeConvert::ToPb(pos, team_data->mutable_pos());
|
||||
TypeConvert::ToPb(attack_dir, team_data->mutable_dir());
|
||||
team_data->set_health(health);
|
||||
team_data->set_health(GetHP());
|
||||
team_data->set_max_health(GetMaxHP());
|
||||
team_data->set_disconnected(false);
|
||||
team_data->set_dead(dead);
|
||||
@ -423,9 +424,14 @@ float Human::GetRadius()
|
||||
return meta->i->radius();
|
||||
}
|
||||
|
||||
float Human::GetHP()
|
||||
{
|
||||
return ability.hp;
|
||||
}
|
||||
|
||||
float Human::GetMaxHP()
|
||||
{
|
||||
return meta->i->health();
|
||||
return ability.max_hp;
|
||||
}
|
||||
|
||||
void Human::UpdatePoisoning()
|
||||
@ -546,7 +552,6 @@ void Human::BeKill(int killer_id, const std::string& killer_name, int weapon_id)
|
||||
stats.killer_name = killer_name;
|
||||
stats.weapon_id = weapon_id;
|
||||
dead = true;
|
||||
health = 0.0f;
|
||||
dead_frameno = room->frame_no;
|
||||
room->xtimer.AddDeadLineTimerAndAttach(MetaMgr::Instance()->revive_time * SERVER_FRAME_RATE,
|
||||
a8::XParams()
|
||||
@ -590,12 +595,12 @@ void Human::DecHP(float dec_hp, int killer_id, const std::string& killer_name, i
|
||||
if (energy_shield > 0.001f) {
|
||||
energy_shield = std::max(0.0f, energy_shield - dec_hp);
|
||||
} else {
|
||||
float old_health = health;
|
||||
health = std::max(0.0f, health - dec_hp);
|
||||
if (health - old_health > 0.001f) {
|
||||
stats.damage_amount_in += health - old_health;
|
||||
float old_health = GetHP();
|
||||
ability.hp = std::max(0.0f, GetHP() - dec_hp);
|
||||
if (GetHP() - old_health > 0.001f) {
|
||||
stats.damage_amount_in += GetHP() - old_health;
|
||||
}
|
||||
if (health <= 0.0001f && !dead) {
|
||||
if (GetHP() <= 0.0001f && !dead) {
|
||||
if (downed) {
|
||||
if (downed_timer) {
|
||||
room->xtimer.DeleteTimer(downed_timer);
|
||||
@ -605,7 +610,7 @@ void Human::DecHP(float dec_hp, int killer_id, const std::string& killer_name, i
|
||||
BeKill(killer_id, killer_name, weapon_id);
|
||||
} else {
|
||||
if (HasNoDownedTeammate()) {
|
||||
health = MetaMgr::Instance()->GetSysParamAsInt("downed_recover_hp");
|
||||
ability.hp = MetaMgr::Instance()->GetSysParamAsInt("downed_recover_hp");
|
||||
downed = true;
|
||||
downed_timer = room->xtimer.AddRepeatTimerAndAttach(
|
||||
SERVER_FRAME_RATE,
|
||||
@ -854,7 +859,7 @@ void Human::FillMFActivePlayerData(cs::MFActivePlayerData* player_data)
|
||||
player_data->set_backpack(backpack);
|
||||
player_data->set_helmet(helmet);
|
||||
player_data->set_chest(chest);
|
||||
player_data->set_health(health);
|
||||
player_data->set_health(GetHP());
|
||||
player_data->set_max_health(GetMaxHP());
|
||||
player_data->set_cur_weapon_idx(curr_weapon->weapon_idx);
|
||||
player_data->set_cur_scope(curr_scope_idx);
|
||||
@ -906,11 +911,6 @@ bool Human::CanSee(const Human* hum) const
|
||||
return room->grid_service.InView(grid_id, hum->grid_id);
|
||||
}
|
||||
|
||||
void Human::RecalcAttr()
|
||||
{
|
||||
def = meta->i->def();
|
||||
}
|
||||
|
||||
void Human::RecalcVolume()
|
||||
{
|
||||
MetaData::Equip* backpack_meta = MetaMgr::Instance()->GetEquip(backpack);
|
||||
@ -921,11 +921,6 @@ void Human::RecalcVolume()
|
||||
}
|
||||
}
|
||||
|
||||
void Human::RecalcBuff()
|
||||
{
|
||||
ability = HumanAbility();
|
||||
}
|
||||
|
||||
int Human::GetInventory(int slot_id)
|
||||
{
|
||||
if (!IsValidSlotId(slot_id)) {
|
||||
@ -963,8 +958,8 @@ int Human::GetVolume(int slot_id)
|
||||
void Human::RecoverHp(int inc_hp)
|
||||
{
|
||||
if (!dead) {
|
||||
health += inc_hp;
|
||||
health = std::max(health, GetMaxHP());
|
||||
ability.hp += inc_hp;
|
||||
ability.hp = std::max(GetHP(), GetMaxHP());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1255,7 +1250,7 @@ void Human::UpdateAction()
|
||||
return;
|
||||
}
|
||||
if (!hum->dead && hum->downed) {
|
||||
hum->health = MetaMgr::Instance()->GetSysParamAsInt("downed_relive_recover_hp");
|
||||
hum->ability.hp = MetaMgr::Instance()->GetSysParamAsInt("downed_relive_recover_hp");
|
||||
hum->downed = false;
|
||||
if (hum->downed_timer) {
|
||||
room->xtimer.DeleteTimer(hum->downed_timer);
|
||||
@ -1632,6 +1627,59 @@ void Human::CheckGrass()
|
||||
}
|
||||
}
|
||||
|
||||
float* Human::GetAbilityById(int attr_id)
|
||||
{
|
||||
switch (attr_id) {
|
||||
case HAT_Hp:
|
||||
return &ability.hp;
|
||||
break;
|
||||
case HAT_HPRecover:
|
||||
return &ability.hp_recover;
|
||||
break;
|
||||
case HAT_Atk:
|
||||
return &ability.atk;
|
||||
break;
|
||||
case HAT_Def:
|
||||
return &ability.def;
|
||||
break;
|
||||
case HAT_Speed:
|
||||
return &ability.speed;
|
||||
break;
|
||||
case HAT_ShotRange:
|
||||
return &ability.shot_range;
|
||||
break;
|
||||
case HAT_ShotSpeed:
|
||||
return &ability.shot_speed;
|
||||
break;
|
||||
case HAT_ReloadSpeed:
|
||||
return &ability.reload_speed;
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Human::RecalcBaseAttr()
|
||||
{
|
||||
ability = HumanAbility();
|
||||
if (skin_meta) {
|
||||
for (auto& pair : skin_meta->attr_init) {
|
||||
float* p_attr = GetAbilityById(pair.first);
|
||||
if (p_attr) {
|
||||
*p_attr += pair.second;
|
||||
}
|
||||
}
|
||||
for (auto& pair : skin_meta->attr_up) {
|
||||
float* p_attr = GetAbilityById(pair.first);
|
||||
if (p_attr) {
|
||||
*p_attr += (SkinLv() / std::get<1>(pair.second)) * std::get<0>(pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
ability.max_hp = ability.hp;
|
||||
}
|
||||
|
||||
void Human::_UpdateMove(int speed)
|
||||
{
|
||||
for (int i = 0; i < speed; ++i) {
|
||||
@ -1740,7 +1788,7 @@ void Human::DeadDrop()
|
||||
void Human::Revive()
|
||||
{
|
||||
dead = false;
|
||||
health = GetMaxHP();
|
||||
ability.hp = GetMaxHP();
|
||||
{
|
||||
MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(1003);
|
||||
if (buff_meta) {
|
||||
|
@ -53,7 +53,6 @@ class Human : public Entity
|
||||
|
||||
std::string name;
|
||||
std::string avatar_url;
|
||||
float health = 0.0;
|
||||
bool dead = false;
|
||||
bool downed = false;
|
||||
bool disconnected = false;
|
||||
@ -107,7 +106,6 @@ class Human : public Entity
|
||||
|
||||
long long send_msg_times = 0;
|
||||
|
||||
float def = 0.0f;
|
||||
std::map<int, int> weapon_configs;
|
||||
std::map<int, int> skin_configs;
|
||||
|
||||
@ -137,6 +135,7 @@ class Human : public Entity
|
||||
void FindPath();
|
||||
void FindPathInMapService();
|
||||
float GetRadius();
|
||||
float GetHP();
|
||||
float GetMaxHP();
|
||||
void UpdatePoisoning();
|
||||
void UpdateSkill();
|
||||
@ -168,9 +167,7 @@ class Human : public Entity
|
||||
void FillMFActivePlayerData(cs::MFActivePlayerData* player_data);
|
||||
void FillMFGasData(cs::MFGasData* gas_data);
|
||||
bool CanSee(const Human* hum) const;
|
||||
void RecalcAttr();
|
||||
void RecalcVolume();
|
||||
void RecalcBuff();
|
||||
int GetInventory(int slot_id);
|
||||
void AddInventory(int slot_id, int num);
|
||||
void DecInventory(int slot_id, int num);
|
||||
@ -210,6 +207,8 @@ class Human : public Entity
|
||||
void OnEnterGrass();
|
||||
void OnLeaveGrass();
|
||||
void CheckGrass();
|
||||
float* GetAbilityById(int attr_id);
|
||||
void RecalcBaseAttr();
|
||||
|
||||
protected:
|
||||
void _UpdateMove(int speed);
|
||||
|
@ -427,4 +427,71 @@ namespace MetaData
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Driver::Init()
|
||||
{
|
||||
{
|
||||
std::vector<std::string> strings;
|
||||
a8::Split(i->attr_type(), strings, '|');
|
||||
for (auto& str : strings) {
|
||||
std::vector<std::string> strings2;
|
||||
a8::Split(str, strings2, ':');
|
||||
if (strings2.size() != 3) {
|
||||
abort();
|
||||
}
|
||||
int attr_type = a8::XValue(strings2[0]);
|
||||
float attr_value = a8::XValue(strings2[1]).GetDouble();
|
||||
int attr_level = a8::XValue(strings2[2]).GetDouble();
|
||||
attr_up[attr_type] = std::make_tuple(attr_value, attr_level);
|
||||
}
|
||||
}
|
||||
{
|
||||
std::vector<std::string> strings;
|
||||
a8::Split(i->s_attr(), strings, '|');
|
||||
for (auto& str : strings) {
|
||||
std::vector<std::string> strings2;
|
||||
a8::Split(str, strings2, ':');
|
||||
if (strings2.size() != 3) {
|
||||
abort();
|
||||
}
|
||||
int attr_type = a8::XValue(strings2[0]);
|
||||
float attr_value = a8::XValue(strings2[1]).GetDouble();
|
||||
int attr_level = a8::XValue(strings2[2]).GetDouble();
|
||||
passive_skill_attr[attr_type] = std::make_tuple(attr_value, attr_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tank::Init()
|
||||
{
|
||||
{
|
||||
std::vector<std::string> strings;
|
||||
a8::Split(i->attr_origin(), strings, '|');
|
||||
for (auto& str : strings) {
|
||||
std::vector<std::string> strings2;
|
||||
a8::Split(str, strings2, ':');
|
||||
if (strings2.size() != 2) {
|
||||
abort();
|
||||
}
|
||||
int attr_type = a8::XValue(strings2[0]);
|
||||
float attr_value = a8::XValue(strings2[1]).GetDouble();
|
||||
attr_init[attr_type] = attr_value;
|
||||
}
|
||||
}
|
||||
{
|
||||
std::vector<std::string> strings;
|
||||
a8::Split(i->attr_up(), strings, '|');
|
||||
for (auto& str : strings) {
|
||||
std::vector<std::string> strings2;
|
||||
a8::Split(str, strings2, ':');
|
||||
if (strings2.size() != 3) {
|
||||
abort();
|
||||
}
|
||||
int attr_type = a8::XValue(strings2[0]);
|
||||
int attr_level = a8::XValue(strings2[1]).GetDouble();
|
||||
float attr_value = a8::XValue(strings2[2]).GetDouble();
|
||||
attr_up[attr_type] = std::make_tuple(attr_value, attr_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -173,9 +173,22 @@ namespace MetaData
|
||||
const metatable::KillReward* i = nullptr;
|
||||
};
|
||||
|
||||
struct Driver
|
||||
{
|
||||
const metatable::Driver* i = nullptr;
|
||||
|
||||
void Init();
|
||||
std::map<int, std::tuple<float, int>> attr_up;
|
||||
std::map<int, std::tuple<float, int>> passive_skill_attr;
|
||||
};
|
||||
|
||||
struct Tank
|
||||
{
|
||||
const metatable::Tank* i = nullptr;
|
||||
|
||||
void Init();
|
||||
std::map<int, float> attr_init;
|
||||
std::map<int, std::tuple<float, int>> attr_up;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ public:
|
||||
std::list<MetaData::Dress> dress_list;
|
||||
std::list<metatable::Tank> tank_meta_list;
|
||||
std::list<MetaData::Tank> tank_list;
|
||||
std::list<metatable::Driver> driver_meta_list;
|
||||
std::list<MetaData::Driver> driver_list;
|
||||
std::list<metatable::Skill> skill_meta_list;
|
||||
std::list<MetaData::Skill> skill_list;
|
||||
std::list<metatable::Buff> buff_meta_list;
|
||||
@ -61,6 +63,7 @@ public:
|
||||
std::map<std::string, std::vector<MetaData::MapTplThing>> born_point_hash;
|
||||
std::map<int, MetaData::Dress*> dress_hash;
|
||||
std::map<int, MetaData::Tank*> tank_hash;
|
||||
std::map<int, MetaData::Driver*> driver_hash;
|
||||
std::map<int, MetaData::Skill*> skill_hash;
|
||||
std::map<int, MetaData::Buff*> buff_hash;
|
||||
std::map<int, MetaData::Attr*> attr_id_hash;
|
||||
@ -90,6 +93,7 @@ public:
|
||||
f8::ReadCsvMetaFile(res_path + "map@map.csv", map_meta_list);
|
||||
f8::ReadCsvMetaFile(res_path + "safearea@safearea.csv", safearea_meta_list);
|
||||
f8::ReadCsvMetaFile(res_path + "tank@tank.csv", tank_meta_list);
|
||||
f8::ReadCsvMetaFile(res_path + "driver@driver.csv", driver_meta_list);
|
||||
f8::ReadCsvMetaFile(res_path + "item@item.csv", item_meta_list);
|
||||
f8::ReadCsvMetaFile(res_path + "equip@equip.csv", equip_meta_list);
|
||||
f8::ReadCsvMetaFile(res_path + "player@player.csv", player_meta_list);
|
||||
@ -190,9 +194,17 @@ private:
|
||||
for (auto& meta : tank_meta_list) {
|
||||
MetaData::Tank& item = a8::FastAppend(tank_list);
|
||||
item.i = &meta;
|
||||
item.Init();
|
||||
tank_hash[item.i->id()] = &item;
|
||||
}
|
||||
|
||||
for (auto& meta : driver_meta_list) {
|
||||
MetaData::Driver& item = a8::FastAppend(driver_list);
|
||||
item.i = &meta;
|
||||
item.Init();
|
||||
driver_hash[item.i->id()] = &item;
|
||||
}
|
||||
|
||||
for (auto& meta : item_meta_list) {
|
||||
MetaData::Item& item = a8::FastAppend(item_list);
|
||||
item.i = &meta;
|
||||
@ -431,6 +443,12 @@ MetaData::Dress* MetaMgr::GetDress(int dress_id)
|
||||
return itr != loader_->dress_hash.end() ? itr->second : nullptr;
|
||||
}
|
||||
|
||||
MetaData::Driver* MetaMgr::GetDriver(int driver_id)
|
||||
{
|
||||
auto itr = loader_->driver_hash.find(driver_id);
|
||||
return itr != loader_->driver_hash.end() ? itr->second : nullptr;
|
||||
}
|
||||
|
||||
MetaData::Tank* MetaMgr::GetTank(int tank_id)
|
||||
{
|
||||
auto itr = loader_->tank_hash.find(tank_id);
|
||||
|
@ -34,6 +34,7 @@ class MetaMgr : public a8::Singleton<MetaMgr>
|
||||
MetaData::Attr* GetAttrById(int attr_id);
|
||||
MetaData::Attr* GetAttrByName(const std::string& attr_name);
|
||||
MetaData::Dress* GetDress(int dress_id);
|
||||
MetaData::Driver* GetDriver(int driver_id);
|
||||
MetaData::Tank* GetTank(int tank_id);
|
||||
float GetRankRewardParam(int rank);
|
||||
float GetKillRewardParam(int kill_num);
|
||||
|
@ -205,7 +205,7 @@ void Obstacle::Explosion()
|
||||
Human* hum = (Human*)target;
|
||||
if (!hum->dead) {
|
||||
float dmg = meta->i->damage();
|
||||
float def = hum->def + hum->ability.def_add;
|
||||
float def = hum->ability.def + hum->ability.def_add;
|
||||
float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K);
|
||||
if (!hum->HasBuffEffect(BET_Invincible)) {
|
||||
hum->DecHP(finaly_dmg, VP_Mine, "地雷", VW_Mine);
|
||||
|
@ -30,13 +30,12 @@ Player::~Player()
|
||||
void Player::Initialize()
|
||||
{
|
||||
Human::Initialize();
|
||||
health = meta->i->health();
|
||||
max_energy_shield = energy_shield;
|
||||
skin_meta = MetaMgr::Instance()->GetTank(SkinId());
|
||||
if (skin_meta) {
|
||||
skill_meta = MetaMgr::Instance()->GetSkill(skin_meta->i->skill_id());
|
||||
}
|
||||
RecalcBuff();
|
||||
RecalcBaseAttr();
|
||||
}
|
||||
|
||||
void Player::Update(int delta_time)
|
||||
|
@ -45,7 +45,6 @@ Player* PlayerMgr::CreatePlayerByCMJoin(long ip_saddr, int socket, const cs::CMJ
|
||||
hum->session_id = msg.session_id();
|
||||
hum->from_appid = msg.from_appid();
|
||||
hum->name = msg.name();
|
||||
hum->health = 0;
|
||||
hum->team_uuid = msg.team_uuid();
|
||||
hum->team_mode = msg.team_mode();
|
||||
hum->auto_fill = msg.auto_fill();
|
||||
|
@ -89,8 +89,17 @@ struct PlayerStats
|
||||
|
||||
struct HumanAbility
|
||||
{
|
||||
float hp = 0.0f;
|
||||
float max_hp = 0.0f;
|
||||
float hp_recover = 0.0f;
|
||||
float atk = 0.0f;
|
||||
float def = 0.0f;
|
||||
float speed = 0.0f;
|
||||
float damage_add = 0.0f;
|
||||
float def_add = 0.0f;
|
||||
float reflect_damage = 0.0f;
|
||||
|
||||
float shot_range = 0.0f;
|
||||
float shot_speed = 0.0f;
|
||||
float reload_speed = 0.0f;
|
||||
};
|
||||
|
@ -98,13 +98,6 @@ message Player
|
||||
{
|
||||
required int32 id = 1; //唯一id
|
||||
required float radius = 2; //半径
|
||||
required int32 health = 3; //初始血量
|
||||
required int32 move_speed = 4; //移动速度
|
||||
required int32 jump_speed = 5; //跳伞速度
|
||||
required int32 move_speed3 = 6;
|
||||
required int32 shot_speed = 7;
|
||||
required int32 move_speed4 = 10; //移动速度4
|
||||
required float def = 11; //防御
|
||||
required string volume = 12; //初始库存
|
||||
}
|
||||
|
||||
@ -204,12 +197,22 @@ message KillReward
|
||||
required float parameter = 2;
|
||||
}
|
||||
|
||||
message Driver
|
||||
{
|
||||
required int32 id = 1;
|
||||
required int32 g_type = 2;
|
||||
required string attr_type = 3;
|
||||
required string s_attr = 4;
|
||||
}
|
||||
|
||||
message Tank
|
||||
{
|
||||
required int32 id = 1;
|
||||
required int32 bullet_id = 2;
|
||||
required int32 max_lv = 3;
|
||||
optional int32 skill_id = 4;
|
||||
required int32 skill_id = 4;
|
||||
required string attr_origin = 5;
|
||||
required string attr_up = 6;
|
||||
}
|
||||
|
||||
//end
|
||||
|
Loading…
x
Reference in New Issue
Block a user