Написание плагинов

iLoco

Пишу плагины за печеньки 🍪🍪🍪
Сообщения
2,265
Реакции
1,323
Когда лучше сохранять в бд данные, при выходе игрока, или при их обновлении?
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
При выходе игрока. Меньше нагрузки на базу.
Но с другой стороны, выше риск и потерять данные, если сервер упадёт.
 

babka68

Участник
Сообщения
2,124
Реакции
956
Всем привет,как исправить?
Была ошибка на 128,добавил проверку в игре ли игрок.
C-подобный:
if (IsPlayerAlive(iClient) && IsClientInGame(iClient))
Не компилируется из за ниже приведенных error логах
1.png
 

Вложения

  • VIP_Multi_Jump.sp
    5.4 КБ · Просмотры: 12

Nekro

Терра инкогнита
Сообщения
4,026
Реакции
2,260
Всем привет,как исправить?
Была ошибка на 128,добавил проверку в игре ли игрок.
C-подобный:
if (IsPlayerAlive(iClient) && IsClientInGame(iClient))
Не компилируется из за ниже приведенных error логах
Посмотреть вложение 66244
У меня компилируется без изменений и ошибок
 

RudikS

Участник
Сообщения
130
Реакции
61
сейчас попробую более новый SM
@Nekro Ты на какой версии Sm компилировал?
Просто замени "Cookie" на что-нибудь другое тот же "cookie".
И сам тип данных "Handle" заменил бы на "Cookie" У тебя смесь нового и старого синтаксиса
 

babka68

Участник
Сообщения
2,124
Реакции
956
Просто замени "Cookie" на что-нибудь другое тот же "cookie".
Спасибо помогло)
И сам тип данных "Handle" заменил бы на "Cookie" У тебя смесь нового и старого синтаксиса
Не я автор,просто пытаюсь добиться корректной работы ресурса),с меня лайк
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,982
@babka68, "Cookie" - это зарезервированное слово просто переименуй этот хэндл
 

Вложения

  • 1603824552979.png
    1603824552979.png
    54.6 КБ · Просмотры: 59

-=|УЧЕНИК|=-

вся жизнь,сплошной цирк.
Сообщения
876
Реакции
212
Привет всем
может кто плагин подправить?
Чтоб лечило когда находишься у елки?
В данный момент не лечит,нечего не происходит
Заранее благодарю
 

Вложения

  • HappyNewYear.sp
    7.9 КБ · Просмотры: 14

RudikS

Участник
Сообщения
130
Реакции
61
Привет всем
может кто плагин подправить?
Чтоб лечило когда находишься у елки?
В данный момент не лечит,нечего не происходит
Заранее благодарю
А где этот плагин взял. На этом форуме нашел 2 с идентичным практически кодом, но без хилла. Тут хилл сделан как-то ужасно.
 

iLoco

Пишу плагины за печеньки 🍪🍪🍪
Сообщения
2,265
Реакции
1,323
Подскажите как можно получить ент рук игрока, а конкретней, как поставить какую-то анимацию рукам (нужно анимировать поднятие предмета).
Уже пробовал:
C-подобный:
FindEntityByClassname(-1, "wearable_item");
FindEntityByClassname(-1, "item_assaultsuit");
GetEntPropEnt(client, Prop_Send, "m_hMyWearables");
 

-=|УЧЕНИК|=-

вся жизнь,сплошной цирк.
Сообщения
876
Реакции
212
А где этот плагин взял. На этом форуме нашел 2 с идентичным практически кодом, но без хилла. Тут хилл сделан как-то ужасно.
Не помню где качал,ну где-то скачен был)
Понятно что ужасно,поэтому и написал сюда
 

RudikS

Участник
Сообщения
130
Реакции
61
Не помню где качал,ну где-то скачен был)
Понятно что ужасно,поэтому и написал сюда
Попробуй так, но тут не через таймер как было, а триггером будет. Некоторые квары вырезал. Кол-во восстановления hp должно быть отрицательным, иначе пойдет урон,
C-подобный:
#include <sourcemod>
#include <sdktools>
#include <cstrike>
#include <sdktools_functions>
#include <sdktools_trace>

public Plugin myinfo =
{
    name = "Happy new year",
    author = "Impulse",
    description = "",
    version = "1.3",
    url = "timetoplay.su"
}

char file[70];

ConVar cvarEnabledHeal;
ConVar cvarHp;
ConVar cvarRadius;

public OnPluginStart()
{
    RegAdminCmd("tree", CreateTree, ADMFLAG_ROOT);
    RegAdminCmd("deltree", DeleteTree, ADMFLAG_ROOT);
    HookEvent("round_start", Start);
   
    cvarEnabledHeal = CreateConVar("ny_enablehp", "1", "1|0 Нужна ли Вам вообще функция выдачи здоровья");
    cvarHp = CreateConVar("ny_hp", "-5", "Сколько добавлять здоровья в зоне ёлочки");
    cvarRadius = CreateConVar("ny_radius", "200.0", "Максимальный радиус от игрока до ёлочки для выдачи здоровья");
   
    AutoExecConfig(true, "newyear", "newyear");
}

public OnMapStart()
{
    PrecacheModel("models/models_kit/xmas/xmastree_mini.mdl",true);
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.dx80.vtx");
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.dx90.vtx");
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.mdl");
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.phy");
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.sw.vtx");
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.vvd");
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.xbox.vtx");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscA.vmt");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscA.vtf");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscA_skin2.vmt");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscA_skin2.vtf");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscB.vmt");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscB.vtf");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscB_skin2.vmt");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscB_skin2.vtf");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscB_spec.vtf");
}

public void Start(Event event, const char []name, bool dontBroadcast)
{
    char MapName[30];
    int i = 0;

    GetCurrentMap(String:MapName, sizeof(MapName));
    Format(String:file, sizeof(file), "cfg/newyear/%s.cfg", MapName);
    KeyValues kv = new KeyValues("tree");
    if (FileToKeyValues(kv, file) && KvGotoFirstSubKey(kv))
    {
            char KeyName[50];
   
            do
            {
                if (KvGetSectionName(kv, KeyName, 50))
                {
                    i++;
                    decl Float:g_fOrigin[3], Float:g_fAngles[3];
                    KvGetVector(kv, "1", g_fOrigin);
                    KvGetVector(kv, "2", g_fAngles);
                    SpawnTree(g_fOrigin, g_fAngles);
                }
         }
         while (KvGotoNextKey(kv));
    }

    PrintToServer("-----------------------", i);
    PrintToServer("Spawned %i tress on map", i);
    PrintToServer("-----------------------", i);
    delete kv;
}

public Action CreateTree(int client, int args)
{
    float g_fOrigin[3], g_fAngles[3];
    GetClientEyePosition(client, g_fOrigin);
    GetClientEyeAngles(client, g_fAngles);  
    TR_TraceRayFilter(g_fOrigin, g_fAngles, MASK_SOLID, RayType_Infinite, Trace_FilterPlayers, client);
    if(TR_DidHit(INVALID_HANDLE))
        {
            TR_GetEndPosition(g_fOrigin, INVALID_HANDLE);
            TR_GetPlaneNormal(INVALID_HANDLE, g_fAngles);
            GetVectorAngles(g_fAngles, g_fAngles);
            g_fAngles[0] += 90.0;
        }
   
    SpawnTree(g_fOrigin, g_fAngles);
    char ar[3];
    GetCmdArgString(ar, sizeof(ar));
    Add(g_fOrigin, g_fAngles, StringToInt(ar));
}

public bool Trace_FilterPlayers(int entity, int contentsMask, any data)
{
    if(entity != data && entity > MaxClients)
        return true;

    return false;
}

public SpawnTree(const float g_fOrigin[3], const float g_fAngles[3])
{
    int index = CreateEntityByName("prop_dynamic");
    DispatchKeyValue(index, "model", "models/models_kit/xmas/xmastree_mini.mdl");
    DispatchKeyValue(index, "Solid", "6");
    DispatchSpawn(index);
    TeleportEntity(index, g_fOrigin, g_fAngles, NULL_VECTOR);
    SetEntityMoveType(index, MOVETYPE_VPHYSICS);

    if (!GetConVarBool(cvarEnabledHeal))
    {
        return;
    }

    char hp[8];
    cvarHp.GetString(hp, sizeof(hp));

    int zone = CreateEntityByName("trigger_hurt");

    float radius = GetConVarFloat(cvarRadius);

    float m_vecMins[3];
    m_vecMins[0] = g_fOrigin[0] - radius;
    m_vecMins[1] = g_fOrigin[1] + radius;
    m_vecMins[2] = g_fOrigin[2] + radius;
   
    float m_vecMaxs[3];
    m_vecMaxs[0] = g_fOrigin[0] + radius;
    m_vecMaxs[1] = g_fOrigin[1] - radius;
    m_vecMaxs[2] = g_fOrigin[2] - radius;

    DispatchKeyValue(zone, "spawnflags", "64");
    DispatchKeyValue(zone, "damagetype", "1024");
    DispatchKeyValue(zone, "damagecap", "5");
    DispatchKeyValue(zone, "damage", hp);
    DispatchSpawn(zone);
    ActivateEntity(zone);
    SetEntProp(zone, Prop_Data, "m_spawnflags", 64);
    TeleportEntity(zone, g_fOrigin, NULL_VECTOR, NULL_VECTOR);
    SetEntityModel(zone, "models/error.mdl");

    m_vecMins[0] = m_vecMins[0] - g_fOrigin[0];
    if (m_vecMins[0] > 0.0)
        m_vecMins[0] *= -1.0;
    m_vecMins[1] = m_vecMins[1] - g_fOrigin[1];
    if (m_vecMins[1] > 0.0)
        m_vecMins[1] *= -1.0;
    m_vecMins[2] = m_vecMins[2] - g_fOrigin[2];
    if (m_vecMins[2] > 0.0)
        m_vecMins[2] *= -1.0;

    m_vecMaxs[0] = m_vecMaxs[0] - g_fOrigin[0];
    if (m_vecMaxs[0] < 0.0)
        m_vecMaxs[0] *= -1.0;
    m_vecMaxs[1] = m_vecMaxs[1] - g_fOrigin[1];
    if (m_vecMaxs[1] < 0.0)
        m_vecMaxs[1] *= -1.0;
    m_vecMaxs[2] = m_vecMaxs[2] - g_fOrigin[2];
    if (m_vecMaxs[2] < 0.0)
        m_vecMaxs[2] *= -1.0;

    SetEntPropVector(zone, Prop_Send, "m_vecMins", m_vecMins);
    SetEntPropVector(zone, Prop_Send, "m_vecMaxs", m_vecMaxs);
    SetEntProp(zone, Prop_Send, "m_usSolidFlags",  152);
}

public void Add(const float Origin[3], const float Angles[3], int ar)
{  
    char info[60];
    Format(info, sizeof(info), "%f,%f",Origin[0], Origin[1]);
    KeyValues kv = new KeyValues("tree");
    FileToKeyValues(kv, String:file);
    KvJumpToKey(kv, info, true);
    KvSetNum(kv, "heal", ar);
    KvSetVector(kv, "1", Origin);
    KvSetVector(kv, "2", Angles);
    KvRewind(kv);
    KeyValuesToFile(kv, file);
    delete kv;
}

public Action DeleteTree(int client, int args)
{
    int index = GetClientAimTarget(client, false);
    if (index  == -1)
        return Plugin_Handled;

    float vec[3];
    char coord[15];
    char coord1[15];

    GetEntPropVector(index, Prop_Data, "m_vecAbsOrigin", vec);
    FloatToString(vec[0], coord, sizeof(coord));
    FloatToString(vec[1], coord1, sizeof(coord1));
   
    char buf3[2][25];
    ExplodeString(String:coord, ".", String:buf3, 2, 25);
   
    char buf4[2][25];
    ExplodeString(String:coord1, ".", String:buf4, 2, 25);
   
    KeyValues kv = new KeyValues("tree");
    if (FileToKeyValues(kv, file) && KvGotoFirstSubKey(kv))
    {
        char KeyName[35];

        do
        {
            if (KvGetSectionName(kv, KeyName, 35))
            {
                char buf[2][25];
                ExplodeString(String:KeyName, ",", String:buf, 2, 25);
               
                char buf1[2][25];
                ExplodeString(String:buf[0], ".", String:buf1, 2, 25);
               
                char buf2[2][25];
                ExplodeString(String:buf[1], ".", String:buf2, 2, 25);
           
           
                if (StrEqual(buf1[0], buf3[0]) && StrEqual(buf2[0], buf4[0]))
                {
                    AcceptEntityInput(index, "Kill");
                    KvDeleteThis(kv);
                    KvRewind(kv);
                    KeyValuesToFile(kv, String:file);
                }
            }
        }
        while (KvGotoNextKey(kv));
    }

    delete kv;
    return Plugin_Continue;
}
 

-=|УЧЕНИК|=-

вся жизнь,сплошной цирк.
Сообщения
876
Реакции
212
Попробуй так, но тут не через таймер как было, а триггером будет. Некоторые квары вырезал. Кол-во восстановления hp должно быть отрицательным, иначе пойдет урон,
C-подобный:
#include <sourcemod>
#include <sdktools>
#include <cstrike>
#include <sdktools_functions>
#include <sdktools_trace>

public Plugin myinfo =
{
    name = "Happy new year",
    author = "Impulse",
    description = "",
    version = "1.3",
    url = "timetoplay.su"
}

char file[70];

ConVar cvarEnabledHeal;
ConVar cvarHp;
ConVar cvarRadius;

public OnPluginStart()
{
    RegAdminCmd("tree", CreateTree, ADMFLAG_ROOT);
    RegAdminCmd("deltree", DeleteTree, ADMFLAG_ROOT);
    HookEvent("round_start", Start);

    cvarEnabledHeal = CreateConVar("ny_enablehp", "1", "1|0 Нужна ли Вам вообще функция выдачи здоровья");
    cvarHp = CreateConVar("ny_hp", "-5", "Сколько добавлять здоровья в зоне ёлочки");
    cvarRadius = CreateConVar("ny_radius", "200.0", "Максимальный радиус от игрока до ёлочки для выдачи здоровья");

    AutoExecConfig(true, "newyear", "newyear");
}

public OnMapStart()
{
    PrecacheModel("models/models_kit/xmas/xmastree_mini.mdl",true);
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.dx80.vtx");
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.dx90.vtx");
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.mdl");
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.phy");
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.sw.vtx");
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.vvd");
    AddFileToDownloadsTable("models/models_kit/xmas/xmastree_mini.xbox.vtx");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscA.vmt");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscA.vtf");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscA_skin2.vmt");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscA_skin2.vtf");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscB.vmt");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscB.vtf");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscB_skin2.vmt");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscB_skin2.vtf");
    AddFileToDownloadsTable("materials/models/models_kit/xmas/xmastree_miscB_spec.vtf");
}

public void Start(Event event, const char []name, bool dontBroadcast)
{
    char MapName[30];
    int i = 0;

    GetCurrentMap(String:MapName, sizeof(MapName));
    Format(String:file, sizeof(file), "cfg/newyear/%s.cfg", MapName);
    KeyValues kv = new KeyValues("tree");
    if (FileToKeyValues(kv, file) && KvGotoFirstSubKey(kv))
    {
            char KeyName[50];

            do
            {
                if (KvGetSectionName(kv, KeyName, 50))
                {
                    i++;
                    decl Float:g_fOrigin[3], Float:g_fAngles[3];
                    KvGetVector(kv, "1", g_fOrigin);
                    KvGetVector(kv, "2", g_fAngles);
                    SpawnTree(g_fOrigin, g_fAngles);
                }
         }
         while (KvGotoNextKey(kv));
    }

    PrintToServer("-----------------------", i);
    PrintToServer("Spawned %i tress on map", i);
    PrintToServer("-----------------------", i);
    delete kv;
}

public Action CreateTree(int client, int args)
{
    float g_fOrigin[3], g_fAngles[3];
    GetClientEyePosition(client, g_fOrigin);
    GetClientEyeAngles(client, g_fAngles);
    TR_TraceRayFilter(g_fOrigin, g_fAngles, MASK_SOLID, RayType_Infinite, Trace_FilterPlayers, client);
    if(TR_DidHit(INVALID_HANDLE))
        {
            TR_GetEndPosition(g_fOrigin, INVALID_HANDLE);
            TR_GetPlaneNormal(INVALID_HANDLE, g_fAngles);
            GetVectorAngles(g_fAngles, g_fAngles);
            g_fAngles[0] += 90.0;
        }

    SpawnTree(g_fOrigin, g_fAngles);
    char ar[3];
    GetCmdArgString(ar, sizeof(ar));
    Add(g_fOrigin, g_fAngles, StringToInt(ar));
}

public bool Trace_FilterPlayers(int entity, int contentsMask, any data)
{
    if(entity != data && entity > MaxClients)
        return true;

    return false;
}

public SpawnTree(const float g_fOrigin[3], const float g_fAngles[3])
{
    int index = CreateEntityByName("prop_dynamic");
    DispatchKeyValue(index, "model", "models/models_kit/xmas/xmastree_mini.mdl");
    DispatchKeyValue(index, "Solid", "6");
    DispatchSpawn(index);
    TeleportEntity(index, g_fOrigin, g_fAngles, NULL_VECTOR);
    SetEntityMoveType(index, MOVETYPE_VPHYSICS);

    if (!GetConVarBool(cvarEnabledHeal))
    {
        return;
    }

    char hp[8];
    cvarHp.GetString(hp, sizeof(hp));

    int zone = CreateEntityByName("trigger_hurt");

    float radius = GetConVarFloat(cvarRadius);

    float m_vecMins[3];
    m_vecMins[0] = g_fOrigin[0] - radius;
    m_vecMins[1] = g_fOrigin[1] + radius;
    m_vecMins[2] = g_fOrigin[2] + radius;

    float m_vecMaxs[3];
    m_vecMaxs[0] = g_fOrigin[0] + radius;
    m_vecMaxs[1] = g_fOrigin[1] - radius;
    m_vecMaxs[2] = g_fOrigin[2] - radius;

    DispatchKeyValue(zone, "spawnflags", "64");
    DispatchKeyValue(zone, "damagetype", "1024");
    DispatchKeyValue(zone, "damagecap", "5");
    DispatchKeyValue(zone, "damage", hp);
    DispatchSpawn(zone);
    ActivateEntity(zone);
    SetEntProp(zone, Prop_Data, "m_spawnflags", 64);
    TeleportEntity(zone, g_fOrigin, NULL_VECTOR, NULL_VECTOR);
    SetEntityModel(zone, "models/error.mdl");

    m_vecMins[0] = m_vecMins[0] - g_fOrigin[0];
    if (m_vecMins[0] > 0.0)
        m_vecMins[0] *= -1.0;
    m_vecMins[1] = m_vecMins[1] - g_fOrigin[1];
    if (m_vecMins[1] > 0.0)
        m_vecMins[1] *= -1.0;
    m_vecMins[2] = m_vecMins[2] - g_fOrigin[2];
    if (m_vecMins[2] > 0.0)
        m_vecMins[2] *= -1.0;

    m_vecMaxs[0] = m_vecMaxs[0] - g_fOrigin[0];
    if (m_vecMaxs[0] < 0.0)
        m_vecMaxs[0] *= -1.0;
    m_vecMaxs[1] = m_vecMaxs[1] - g_fOrigin[1];
    if (m_vecMaxs[1] < 0.0)
        m_vecMaxs[1] *= -1.0;
    m_vecMaxs[2] = m_vecMaxs[2] - g_fOrigin[2];
    if (m_vecMaxs[2] < 0.0)
        m_vecMaxs[2] *= -1.0;

    SetEntPropVector(zone, Prop_Send, "m_vecMins", m_vecMins);
    SetEntPropVector(zone, Prop_Send, "m_vecMaxs", m_vecMaxs);
    SetEntProp(zone, Prop_Send, "m_usSolidFlags",  152);
}

public void Add(const float Origin[3], const float Angles[3], int ar)
{
    char info[60];
    Format(info, sizeof(info), "%f,%f",Origin[0], Origin[1]);
    KeyValues kv = new KeyValues("tree");
    FileToKeyValues(kv, String:file);
    KvJumpToKey(kv, info, true);
    KvSetNum(kv, "heal", ar);
    KvSetVector(kv, "1", Origin);
    KvSetVector(kv, "2", Angles);
    KvRewind(kv);
    KeyValuesToFile(kv, file);
    delete kv;
}

public Action DeleteTree(int client, int args)
{
    int index = GetClientAimTarget(client, false);
    if (index  == -1)
        return Plugin_Handled;

    float vec[3];
    char coord[15];
    char coord1[15];

    GetEntPropVector(index, Prop_Data, "m_vecAbsOrigin", vec);
    FloatToString(vec[0], coord, sizeof(coord));
    FloatToString(vec[1], coord1, sizeof(coord1));

    char buf3[2][25];
    ExplodeString(String:coord, ".", String:buf3, 2, 25);

    char buf4[2][25];
    ExplodeString(String:coord1, ".", String:buf4, 2, 25);

    KeyValues kv = new KeyValues("tree");
    if (FileToKeyValues(kv, file) && KvGotoFirstSubKey(kv))
    {
        char KeyName[35];

        do
        {
            if (KvGetSectionName(kv, KeyName, 35))
            {
                char buf[2][25];
                ExplodeString(String:KeyName, ",", String:buf, 2, 25);
           
                char buf1[2][25];
                ExplodeString(String:buf[0], ".", String:buf1, 2, 25);
           
                char buf2[2][25];
                ExplodeString(String:buf[1], ".", String:buf2, 2, 25);
       
       
                if (StrEqual(buf1[0], buf3[0]) && StrEqual(buf2[0], buf4[0]))
                {
                    AcceptEntityInput(index, "Kill");
                    KvDeleteThis(kv);
                    KvRewind(kv);
                    KeyValuesToFile(kv, String:file);
                }
            }
        }
        while (KvGotoNextKey(kv));
    }

    delete kv;
    return Plugin_Continue;
}
Работает нормально все.
Думаю так даже лучше,чем с таймером
Если не сложно,сделай чтоб хилило по 1 хп и до 70 хп
 
Последнее редактирование:

iLoco

Пишу плагины за печеньки 🍪🍪🍪
Сообщения
2,265
Реакции
1,323
В чём плюсы и минусы одного глобального буфера против куча локальных?
 

Вложения

  • глобальный.png
    глобальный.png
    6.2 КБ · Просмотры: 61
  • локальный.png
    локальный.png
    6.6 КБ · Просмотры: 63
Сверху Снизу