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

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
@babka68, вроде как-то так:
C-подобный:
#pragma semicolon 1
#pragma newdecls required

int
    m_hActiveWeapon,
    m_iPrimaryAmmoType,
    m_iAmmo,
    iMaxType;

public Plugin myinfo =
{
    name        = "Death Match -- Weapon Reload",
    version        = "1.0",
    description    = "Пополнение патронов",
    author        = "babka68"
}

public void OnPluginStart()
{
    if((m_hActiveWeapon = FindSendPropInfo("CBasePlayer", "m_hActiveWeapon")) < 1)
        SetFailState("Unable to find offset CBasePlayer::m_hActiveWeapon!");
    if((m_iPrimaryAmmoType = FindSendPropInfo("CBaseCombatWeapon", "m_iPrimaryAmmoType")) < 1)
        SetFailState("Unable to find offset CBaseCombatWeapon::m_iPrimaryAmmoType!");
    if((m_iAmmo = FindSendPropInfo("CCSPlayer", "m_iAmmo")) < 1)
        SetFailState("Unable to find offset CCSPlayer::m_iAmmo!");

    iMaxType = GetEngineVersion() == Engine_CSGO ? 14 : 11;    // блочим пополнение гранат

    HookEvent("weapon_reload", Event_CheckDepleted);
    HookEvent("weapon_fire_on_empty", Event_CheckDepleted);
    HookEvent("player_death", Event_Death);
}

public void Event_CheckDepleted(Event event, const char[] name, bool dontBroadcast)
{
    int client = GetClientOfUserId(event.GetInt("userid"));
    if(!client || !IsClientInGame(client)) return;

    int wpn = GetEntDataEnt2(client, m_hActiveWeapon);
    if(wpn < 1) return;

    int type = GetEntData(wpn, m_iPrimaryAmmoType);
    if(type < iMaxType) SetEntData(client, (m_iAmmo + type * 4), 300, 4, true);
}

public void Event_Death(Event event, const char[] name, bool dontBroadcast)
{
    if(!event.GetBool("headshot")) return;

    int client = GetClientOfUserId(event.GetInt("attacker"));
    if(!client || !IsClientInGame(client)) return;

    int wpn = GetEntDataEnt2(client, m_hActiveWeapon);
    if(wpn < 1) return;

    int type = GetEntData(wpn, m_iPrimaryAmmoType);
    if(type < iMaxType) SetEntProp(wpn, Prop_Data, "m_iClip1", 30);    // 30 патронов в магазине
}
 
Последнее редактирование:

babka68

Участник
Сообщения
2,124
Реакции
956
@babka68, вроде как-то так:
C-подобный:
#pragma semicolon 1
#pragma newdecls required

int
    m_hActiveWeapon,
    m_iPrimaryAmmoType,
    m_iAmmo,
    iMaxType;

public Plugin myinfo =
{
    name        = "Death Match -- Weapon Reload",
    version        = "1.0",
    description    = "Пополнение патронов",
    author        = "babka68"
}

public void OnPluginStart()
{
    if((m_hActiveWeapon = FindSendPropInfo("CBasePlayer", "m_hActiveWeapon")) < 1)
        SetFailState("Unable to find offset CBasePlayer::m_hActiveWeapon!");
    if((m_iPrimaryAmmoType = FindSendPropInfo("CBaseCombatWeapon", "m_iPrimaryAmmoType")) < 1)
        SetFailState("Unable to find offset CBaseCombatWeapon::m_iPrimaryAmmoType!");
    if((m_iAmmo = FindSendPropInfo("CCSPlayer", "m_iAmmo")) < 1)
        SetFailState("Unable to find offset CCSPlayer::m_iAmmo!");

    iMaxType = GetEngineVersion() == Engine_CSGO ? 14 : 11;    // блочим пополнение гранат

    HookEvent("weapon_reload", Event_CheckDepleted);
    HookEvent("weapon_fire_on_empty", Event_CheckDepleted);
    HookEvent("player_death", Event_Death);
}

public void Event_CheckDepleted(Event event, const char[] name, bool dontBroadcast)
{
    int client = GetClientOfUserId(event.GetInt("userid"));
    if(!client || !IsClientInGame(client)) return;

    int wpn = GetEntDataEnt2(client, m_hActiveWeapon);
    if(wpn < 1) return;

    int type = GetEntData(wpn, m_iPrimaryAmmoType);
    if(type < iMaxType) SetEntProp(client, Prop_Send, "m_iAmmo", 300, _, m_iPrimaryAmmoType);
}

public void Event_Death(Event event, const char[] name, bool dontBroadcast)
{
    if(!event.GetBool("headshot")) return;

    int client = GetClientOfUserId(event.GetInt("attacker"));
    if(!client || !IsClientInGame(client)) return;

    int wpn = GetEntDataEnt2(client, m_hActiveWeapon);
    if(wpn < 1) return;

    int type = GetEntData(wpn, m_iPrimaryAmmoType);
    if(type < iMaxType) SetEntProp(wpn, Prop_Data, "m_iClip1", 30);    // 30 патронов в магазине
}
Как всегда лучший,пойду протестирую,хотя немного по другому уже написал,но не с таким функционалом пока что)
Сообщения автоматически склеены:

@Grey83
C-подобный:
L 12/12/2020 - 23:50:02: SourceMod error session started
L 12/12/2020 - 23:50:02: Info (map "de_dust2") (file "/servers/css/1035/cstrike/addons/sourcemod/logs/errors_20201212.log")
L 12/12/2020 - 23:50:02: [SM] Exception reported: Element 1212 is out of bounds (Prop m_iAmmo has 32 elements).
L 12/12/2020 - 23:50:02: [SM] Blaming: test.smx
L 12/12/2020 - 23:50:02: [SM] Call stack trace:
L 12/12/2020 - 23:50:02: [SM]   [0] SetEntProp
L 12/12/2020 - 23:50:02: [SM]   [1] Line 43, C:\Users\Создание Серверов\Desktop\test.sp::Event_CheckDepleted

При headshot только пополняется в магазине
 
Последнее редактирование:

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
@babka68, исправил на тот код, что у меня в плагине задействован.
Обновил в предыдущем сообщении строку 43:
C-подобный:
if(type < iMaxType) SetEntData(client, (m_iAmmo + type * 4), 300, 4, true);
 

🟡differend🟢

Что хочу - то и делаю
Сообщения
975
Реакции
661
Памагите паЖалста. ClutchTimer.smx (Clutch Timer): Native "Store_GetClientCredits" was not found.
 

Вложения

  • ClutchTimer.sp
    7.3 КБ · Просмотры: 6

KiKiEEKi

🏆 🥇
Сообщения
653
Реакции
513
Здравствуйте, есть или кто сможет написать плагин который будет регулировать громкость всех звуков на сервере или от wcs (без исходника).

Если нельзя такое сделать то можно как то дефолтно выключать в настройках личного кабинета вкс'a игрокам звук скилов?
в .inc есть вот такой натив
wcs.inc:
/**
 * Get client's 'Mute Sound' opt Status.
 *
 * @param index    An integer.
 * @return        Mute Sound opt Status.
 */
native bool:WCS_GetMuteSound(index);
 

Вложения

  • wcs.inc
    11.8 КБ · Просмотры: 1

Madness aka null138

Участник
Сообщения
713
Реакции
734
Здравствуйте, есть или кто сможет написать плагин который будет регулировать громкость всех звуков на сервере или от wcs (без исходника).

Если нельзя такое сделать то можно как то дефолтно выключать в настройках личного кабинета вкс'a игрокам звук скилов?
в .inc есть вот такой натив
wcs.inc:
/**
* Get client's 'Mute Sound' opt Status.
*
* @param index    An integer.
* @return        Mute Sound opt Status.
*/
native bool:WCS_GetMuteSound(index);
C++:
#include <sourcemod>
#include <sdktools>

public void OnPluginStart()
{
    AddNormalSoundHook(HookSounds);
}

public Action HookSounds(int clients[64], int &numClients, char[] sample, int &entity, int &channel, float &volume, int &level, int &pitch, int &flags)
{
    if(StrContains(sample, "wcs", false) != -1)
    {
        volume = 0.1;
        return Plugin_Changed;
    }
    return Plugin_Continue;
}
 

KiKiEEKi

🏆 🥇
Сообщения
653
Реакции
513
C++:
#include <sourcemod>
#include <sdktools>

public void OnPluginStart()
{
    AddNormalSoundHook(HookSounds);
}

public Action HookSounds(int clients[64], int &numClients, char[] sample, int &entity, int &channel, float &volume, int &level, int &pitch, int &flags)
{
    if(StrContains(sample, "wcs", false) != -1)
    {
        volume = 0.1;
        return Plugin_Changed;
    }
    return Plugin_Continue;
}
1608032047321.png
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
@KiKiEEKi, проверяй:
C-подобный:
#include <sdktools_sound>

public void OnPluginStart()
{
    AddNormalSoundHook(HookSounds);
}

public Action HookSounds(int clients[MAXPLAYERS], int &numClients, char sample[PLATFORM_MAX_PATH], int &entity, int &channel, float &volume, int &level, int &pitch, int &flags, char soundEntry[PLATFORM_MAX_PATH], int &seed)
{
    if(StrContains(sample, "wcs", false) != -1)
    {
        volume = 0.1;
        return Plugin_Changed;
    }
    return Plugin_Continue;
}
 

LEII4A

Участник
Сообщения
741
Реакции
135
C++:
#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#include <cstrike>
#define VERSION "1.1.8"

public Plugin:myinfo =
{
    name = "Warmup Round",
    author = "XARiUS",
    description = "Simple warmup round plugin.",
    version = "1.1.8",
    url = "http://www.the-otc.com/"
};

new String:language[4];
new String:languagecode[4];
new String:g_weapon[32];
new String:g_preexec[32];
new String:g_postexec[32];
new bool:IsWarmup;
new bool:g_enabled;
new bool:g_respawn;
new bool:g_friendlyfire;
new g_time;
new timesrepeated;

new Handle:g_Cvarenabled = INVALID_HANDLE;
new Handle:g_Cvartime = INVALID_HANDLE;
new Handle:g_Cvarweapon = INVALID_HANDLE;
new Handle:g_Cvarrespawn = INVALID_HANDLE;
new Handle:g_Cvarfriendlyfire = INVALID_HANDLE;
new Handle:g_Cvarpreexec = INVALID_HANDLE;
new Handle:g_Cvarpostexec = INVALID_HANDLE;
new Handle:g_Cvaractive = INVALID_HANDLE;
new Handle:g_warmuptimer = INVALID_HANDLE;

new g_iMyWeapons;

public OnPluginStart()
{
  LoadTranslations("warmup.phrases");
  CreateConVar("sm_warmupround_version", VERSION, "Warmup Round Version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD);
  g_Cvaractive = CreateConVar("sm_warmupround_active", "0", "DO NOT MODIFY THIS VALUE DIRECTLY - USED FOR STATS TRACKING", FCVAR_DONTRECORD);
  g_Cvarenabled = CreateConVar("sm_warmupround_enabled", "1", "Enable this plugin. 0 = Disabled");
  g_Cvartime = CreateConVar("sm_warmupround_time", "30", "Time in seconds for the warmup to last.  Minimum 15.", _, true, 15.0, true, 120.0);
  g_Cvarweapon = CreateConVar("sm_warmupround_weapon", "hegrenade", "Weapon to give players during warmup.  HEGrenades are unlimted.  Examples: knife,deagle,fiveseven,elite,p228..");
  g_Cvarrespawn = CreateConVar("sm_warmupround_respawn", "1", "Respawn players during warmup. 0 = Disabled");
  g_Cvarfriendlyfire = CreateConVar("sm_warmupround_friendlyfire", "0", "Disable friendly fire during warmup. (Use this if you keep friendly fire ON normally) 0 = Disabled");
  g_Cvarpreexec = CreateConVar("sm_warmupround_preexec", "", "Config file to execute prior to warmup round starting.  File goes in /cfg/ directory.  (Example: 'prewarmup.cfg' | Leave blank for none)");
  g_Cvarpostexec = CreateConVar("sm_warmupround_postexec", "", "Config file to execute after warmup round has ended.  File goes in /cfg/ directory.  (Example: 'postwarmup.cfg' | Leave blank for none)");
  GetLanguageInfo(GetServerLanguage(), languagecode, sizeof(languagecode), language, sizeof(language));

  HookEvent("player_death", EventPlayerDeath, EventHookMode_Post);
  HookEvent("item_pickup", EventItemPickup, EventHookMode_Post);
  HookEvent("weapon_fire", EventWeaponFire, EventHookMode_Post);
 
  HookConVarChange(g_Cvarenabled, OnSettingChanged);
  HookConVarChange(g_Cvartime, OnSettingChanged);
  HookConVarChange(g_Cvarweapon, OnSettingChanged);
  HookConVarChange(g_Cvarrespawn, OnSettingChanged);
  HookConVarChange(g_Cvarfriendlyfire, OnSettingChanged);
  HookConVarChange(g_Cvarpreexec, OnSettingChanged);
  HookConVarChange(g_Cvarpostexec, OnSettingChanged);

  g_enabled = GetConVarBool(g_Cvarenabled);
  g_respawn = GetConVarBool(g_Cvarrespawn);
  g_friendlyfire = GetConVarBool(g_Cvarfriendlyfire);
  g_time = GetConVarInt(g_Cvartime);
  GetConVarString(g_Cvarpreexec, g_preexec, sizeof(g_preexec));
  GetConVarString(g_Cvarpostexec, g_postexec, sizeof(g_postexec));
  GetConVarString(g_Cvarweapon, g_weapon, sizeof(g_weapon));
  timesrepeated = g_time;
  IsWarmup = false;
  SetupOffsets();
 
  AutoExecConfig(true, "warmup");
}

SetupOffsets()
{
  g_iMyWeapons = FindSendPropOffs("CBaseCombatCharacter", "m_hMyWeapons");
  if (g_iMyWeapons == -1)
  {
    SetFailState("[Warmup] Error - Unable to get offset for CBaseCombatCharacter::m_hMyWeapons");
  }
}

public OnSettingChanged(Handle:convar, const String:oldValue[], const String:newValue[])
{
  if (convar == g_Cvarenabled)
  {
    if (newValue[0] == '1')
    {
            g_enabled = true;
    }
    else
    {
      g_enabled = false;
    }
  }
  if (convar == g_Cvarrespawn)
  {
    if (newValue[0] == '1')
    {
            g_respawn = true;
    }
    else
    {
      g_respawn = false;
    }
  }
  if (convar == g_Cvarfriendlyfire)
  {
    if (newValue[0] == '1')
    {
            g_friendlyfire = true;
    }
    else
    {
      g_friendlyfire = false;
    }
  }
  if (convar == g_Cvartime)
  {
    g_time = StringToInt(newValue);
  }
  if (convar == g_Cvarweapon)
  {
    CheckWeaponString(newValue);
  }
  if (convar == g_Cvarpreexec)
  {
    strcopy(g_preexec, sizeof(g_preexec), newValue);
  }
  if (convar == g_Cvarpostexec)
  {
    strcopy(g_postexec, sizeof(g_postexec), newValue);
  }
}

public OnAutoConfigsBuffered()
{
  if (g_warmuptimer != INVALID_HANDLE)
  {
    KillTimer(g_warmuptimer);
  }
  if (g_enabled)
    {
    SetConVarBool(g_Cvaractive, true, false, false);
    timesrepeated = g_time;
    IsWarmup = true;
    new String:buffer[32] = "cfg/";
    StrCat(buffer, sizeof(buffer), g_preexec);
    if (FileExists(buffer))
    {
      ServerCommand("exec %s", g_preexec);
    }
    if (g_friendlyfire)
    {
      ServerCommand("mp_friendlyfire 0");
    }
    g_warmuptimer = CreateTimer(1.0, Countdown, _, TIMER_REPEAT);
    }
}

public CheckWeaponString(const String:weapon[])
{
  new String:weapons[26][32];
  new bool:valid = false;
 
  weapons[0] = "glock";
  weapons[1] = "usp";
  weapons[2] = "p228";
  weapons[3] = "deagle";
  weapons[4] = "elite";
  weapons[5] = "fiveseven";
  weapons[6] = "m3";
  weapons[7] = "xm1014";
  weapons[8] = "mac10";
  weapons[9] = "tmp";
  weapons[10] = "mp5navy";
  weapons[11] = "ump45";
  weapons[12] = "p90";
  weapons[13] = "galil";
  weapons[14] = "famas";
  weapons[15] = "ak47";
  weapons[16] = "m4a1";
  weapons[17] = "sg552";
  weapons[18] = "aug";
  weapons[19] = "m249";
  weapons[20] = "scout";
  weapons[21] = "awp";
  weapons[22] = "g3sg1";
  weapons[23] = "sg550";
  weapons[24] = "hegrenade";
  weapons[25] = "knife";
 
  for (new i = 0; i <= 25; i++)
  {
    if (StrEqual(weapon, weapons[i], false))
    {
      valid = true;
    }
  }
  if (!valid)
  {
    PrintToServer("[Warmup Round] Weapon selection: %s, is not valid.  Please try setting sm_warmupround_weapon again.", weapon);
    g_weapon = "hegrenade";
  }
  else
  {
    PrintToServer("[Warmup Round] Weapon selection changed to: %s", weapon);
    strcopy(g_weapon, sizeof(g_weapon), weapon);
  }
}

public Action:CancelWarmup()
{
  SetConVarBool(g_Cvaractive, false, false, false);
  g_warmuptimer = INVALID_HANDLE;
  IsWarmup = false;
  ServerCommand("mp_restartgame 1");
  new String:buffer[32] = "cfg/";
  StrCat(buffer, sizeof(buffer), g_postexec);
  if (FileExists(buffer))
  {
    ServerCommand("exec %s", g_postexec);
  }
  if (g_friendlyfire)
  {
    ServerCommand("mp_friendlyfire 1");
  }
} 

WeaponHandler(client)
{
    if (IsWarmup && client != 0)
    {
        new String:buffer[32];
        static Slot = 0, EntityIndex = 0;
        decl String:WeaponClass[64] = "";
        for (Slot = 0; Slot <= (32 * 4); Slot += 4)
        {
            if (IsValidEdict(GetEntDataEnt2(client, (g_iMyWeapons + Slot))))
            {
                EntityIndex = GetEntDataEnt2(client, (g_iMyWeapons + Slot));
                GetEdictClassname(EntityIndex, WeaponClass, sizeof(WeaponClass));
                if (StrEqual(WeaponClass, "worldspawn", false))
                {
                    return;
                }
                RemovePlayerItem(client, EntityIndex);
                RemoveEdict(EntityIndex);
            }
        }
        if (strlen(g_weapon) > 2)
        {
            Format(buffer, sizeof(buffer), "weapon_%s", g_weapon);
            GivePlayerItem(client, buffer);
        }
        Slot = 0;
        EntityIndex = 0;
    }
} 

public Action:Countdown(Handle:timer)
{
  if (IsWarmup)
  {
    if (timesrepeated >= 1)
    {
      PrintCenterTextAll("Разминка: осталось %i сек.", timesrepeated);
      timesrepeated--;
    }
    else if (timesrepeated == 0)
    {
      timesrepeated = g_time;
      CancelWarmup();
      return Plugin_Stop;
    }
  }
  else
  {
    timesrepeated = g_time;
    return Plugin_Stop;
  }
  return Plugin_Continue;
}

public Action:DelayWeapon(Handle:timer, any:client)
{
  WeaponHandler(client);
}

public Action:SpawnPlayer(Handle:timer, any:client)
{
  if (IsClientInGame(client))
  {
    CS_RespawnPlayer(client);
  }
}

public EventItemPickup(Handle:event, const String:name[],bool:dontBroadcast)
{
    if (g_enabled && IsWarmup)
  {
    new clientid = GetClientOfUserId(GetEventInt(event, "userid"));
    new String:item[32];
    GetEventString(event, "item", item, sizeof(item));
    if (!StrEqual(item, g_weapon, false))
    {
      CreateTimer(0.1, DelayWeapon, clientid);
    }
  }
}

public EventWeaponFire(Handle:event,const String:name[],bool:dontBroadcast)
{
  if (g_enabled && IsWarmup)
  {
    if (StrEqual(g_weapon, "hegrenade", false))
    {
      new clientid = GetClientOfUserId(GetEventInt(event, "userid"));
      new String:weapon[32];
      GetEventString(event, "weapon", weapon, sizeof(weapon));
      if (StrEqual(weapon, "hegrenade", false))
      {
        CreateTimer(1.1, DelayWeapon, clientid);
      }
    }
  }
}
public EventPlayerDeath(Handle:event,const String:name[],bool:dontBroadcast)
{
  if (g_enabled && IsWarmup && g_respawn)
  {
    new clientid = GetClientOfUserId(GetEventInt(event, "userid"));
    CreateTimer(0.5, SpawnPlayer, clientid);
  }
}
Добрый вечер. Кто нибудь может добавить очистку оружия на карте во время разминки? ну или в целом поправить ошибки, если есть баги
 

LEII4A

Участник
Сообщения
741
Реакции
135
@LEII4A, метод чистки можно глянуть у меня в коде вот тут: Gun Menu
Спасибо конечно, но как сделать, чтобы оружие было очищено чисто на разминке, а не всю карту?
Нашел такой вот плагин
C++:
/*
    SM Weapon Cleanup bY TechKnow
    
    
*/

#include <sourcemod>
#include <sdktools>

#define PLUGIN_VERSION "1.2"




public Plugin:myinfo =
{
    name = "SM Weapon Cleanup",
    author = "TechKnow",
    description = "Removes loose weapons droped",
    version = PLUGIN_VERSION,
    url = "http://www.sourcemod.net/"
};



new Handle:Cvar_Removeweapons;
new g_WeaponParent;

public OnPluginStart()
{
    CreateConVar("sm_Weaponcleanup_version", PLUGIN_VERSION, "WeaponCleanup version",     FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);

    Cvar_Removeweapons = CreateConVar("Removeweapons_on", "1", "1 Removeweapons on 0 is off", FCVAR_PLUGIN|FCVAR_REPLICATED|FCVAR_NOTIFY);

    g_WeaponParent = FindSendPropOffs("CBaseCombatWeapon", "m_hOwnerEntity");

        RegAdminCmd("sm_cleanup", Command_Manual, ADMFLAG_SLAY);

    HookEventEx("player_death", Cleanup, EventHookMode_Post);

    HookEventEx("round_start", Cleanup, EventHookMode_Post);
}

public Action:Cleanup(Handle:event,const String:name[],bool:dontBroadcast)
{
        // By Kigen (c) 2008 - Please give me credit. :)
        if (!GetConVarBool(Cvar_Removeweapons))
    {
        return Plugin_Continue;
    }
    new maxent = GetMaxEntities(), String:weapon[64];
    for (new i=GetMaxClients();i<maxent;i++)
    {
        if ( IsValidEdict(i) && IsValidEntity(i) )
        {
            GetEdictClassname(i, weapon, sizeof(weapon));
            if ( ( StrContains(weapon, "weapon_") != -1 || StrContains(weapon, "item_") != -1 ) && GetEntDataEnt2(i, g_WeaponParent) == -1 )
                    RemoveEdict(i);
        }
    }   
    return Plugin_Continue;
}

public Action:Command_Manual(client, args)
{
        // By Kigen (c) 2008 - Please give me credit. :)
    new maxent = GetMaxEntities(), String:weapon[64];
    for (new i=GetMaxClients();i<maxent;i++)
    {
        if ( IsValidEdict(i) && IsValidEntity(i) )
        {
            GetEdictClassname(i, weapon, sizeof(weapon));
            if ( ( StrContains(weapon, "weapon_") != -1 || StrContains(weapon, "item_") != -1 ) && GetEntDataEnt2(i, g_WeaponParent) == -1 )
                    RemoveEdict(i);
        }
    }   
    return Plugin_Continue;
}
 

Paranoiiik

хачю клиентмод
Сообщения
2,047
Реакции
1,490
Не знает ли никто, как можно получить время, которое игрок пробыл на сервере?
Хочу в логе при дисконнекте написать [Время сессии - n-часов, n-минут, n-секунд] или что-то типа того
 

Nekro

Терра инкогнита
Сообщения
4,025
Реакции
2,260
Не знает ли никто, как можно получить время, которое игрок пробыл на сервере?
Хочу в логе при дисконнекте написать [Время сессии - n-часов, n-минут, n-секунд] или что-то типа того
По идеи должен быть эвент так как при просмотре онлайна сервера отображает из время
 

Paranoiiik

хачю клиентмод
Сообщения
2,047
Реакции
1,490
По идеи должен быть эвент так как при просмотре онлайна сервера отображает из время
Спасибо, не догадался до этого.
Похоже, это GetClientTime. Теперь буду пытаться понять, как обозначить это в коде
 

RusJJ

Доброе утро девачьки
Сообщения
2,582
Реакции
1,075
@Paranoiiik, оно будет считать и время загрузки. То есть если игрок 5 минут качал файлы, то 5 минут учитываются.
 
Сверху Снизу