Билд SM 1.11 под ксс34 старее чем SM 1.11 на котором ты компилируешь (Чаще из-за этого в твоем случае)Подскажите что за ошибка. CSS v34. SM 1.11
L 10/12/2023 - 01:14:01: [SM] Failed to load plugin "round_end_music.smx": Unable to load plugin (unsupported feature set; code is too new).
Удалите лишние плейлисты, у меня 1 для всех стоитНикто не сталкивался с такой проблемой, у всех играет разная музыка)
Так и задумано вроде, разве нет?Никто не сталкивался с такой проблемой, у всех играет разная музыка)
Стоит 1 плейлист для всехУдалите лишние плейлисты, у меня 1 для всех стоит
#include <sourcemod>
#include <sdktools>
#pragma newdecls required
#pragma semicolon 1
public Plugin myinfo = {
name = "Round End Music (Manual Tags)",
author = "Google Ai",
version = "1"
};
ConVar cv_AnnounceEvery, cv_SoundsList, cv_Display;
ArrayList g_hTracks[16];
ArrayList g_hTrackNames[16];
char g_sPlaylistNames[16][64];
int g_iPlaylistCount = 0;
int g_iClientVolume[MAXPLAYERS + 1];
int g_iClientPlaylist[MAXPLAYERS + 1];
public void OnPluginStart() {
cv_AnnounceEvery = CreateConVar("sm_res_announceevery", "120", "Interval !res");
cv_SoundsList = CreateConVar("sm_res_soundslist", "cfg/sourcemod/rock.txt,cfg/sourcemod/rap.txt", "Playlists");
cv_Display = CreateConVar("sm_res_displaysound", "1", "Show track info");
AutoExecConfig(true, "res");
HookEvent("round_end", Event_RoundEnd);
RegConsoleCmd("sm_res", Command_Res);
for (int i = 0; i < 16; i++) {
g_hTracks[i] = new ArrayList(PLATFORM_MAX_PATH);
g_hTrackNames[i] = new ArrayList(128);
}
CreateTimer(cv_AnnounceEvery.FloatValue, Timer_Announce, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
}
public void OnClientPutInServer(int client) {
g_iClientVolume[client] = 100;
g_iClientPlaylist[client] = 0;
}
public void OnMapStart() {
LoadAllPlaylists();
}
void LoadAllPlaylists() {
g_iPlaylistCount = 0;
char sBuffer[1024], sParts[16][PLATFORM_MAX_PATH];
cv_SoundsList.GetString(sBuffer, sizeof(sBuffer));
int count = ExplodeString(sBuffer, ",", sParts, 16, PLATFORM_MAX_PATH);
for (int i = 0; i < count; i++) {
TrimString(sParts[i]);
if (sParts[i][0] == '\0') continue;
char sPath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, sPath, sizeof(sPath), "../../%s", sParts[i]);
if (g_iPlaylistCount >= 16) break;
if (!FileExists(sPath)) {
File hNewFile = OpenFile(sPath, "w");
if (hNewFile != null) {
hNewFile.WriteLine("// Формат: путь/к/файлу.mp3 * Исполнитель - Название");
if (i == 0) hNewFile.WriteLine("ambient/music/bongo.wav * Прикольные Бонго");
else hNewFile.WriteLine("ambient/music/flamenco.wav * Испанские гитары");
delete hNewFile;
}
}
int lastSlash = FindCharInString(sParts[i], '/', true);
if (lastSlash == -1) strcopy(g_sPlaylistNames[g_iPlaylistCount], 64, sParts[i]);
else strcopy(g_sPlaylistNames[g_iPlaylistCount], 64, sParts[i][lastSlash + 1]);
ReplaceString(g_sPlaylistNames[g_iPlaylistCount], 64, ".txt", "");
g_hTracks[g_iPlaylistCount].Clear();
g_hTrackNames[g_iPlaylistCount].Clear();
File hFile = OpenFile(sPath, "r");
if (hFile != null) {
char sLine[256];
while (hFile.ReadLine(sLine, sizeof(sLine))) {
TrimString(sLine);
if (sLine[0] == '\0' || sLine[0] == '/' || sLine[0] == '#') continue;
char sTrackPath[PLATFORM_MAX_PATH], sTrackName[128];
int starIdx = FindCharInString(sLine, '*');
if (starIdx != -1) {
strcopy(sTrackPath, (starIdx < PLATFORM_MAX_PATH) ? starIdx + 1 : PLATFORM_MAX_PATH, sLine);
TrimString(sTrackPath);
strcopy(sTrackName, sizeof(sTrackName), sLine[starIdx + 1]);
TrimString(sTrackName);
} else {
strcopy(sTrackPath, sizeof(sTrackPath), sLine);
int slash = FindCharInString(sTrackPath, '/', true);
if (slash == -1) strcopy(sTrackName, sizeof(sTrackName), sTrackPath);
else strcopy(sTrackName, sizeof(sTrackName), sTrackPath[slash + 1]);
ReplaceString(sTrackName, sizeof(sTrackName), ".mp3", "");
ReplaceString(sTrackName, sizeof(sTrackName), ".wav", "");
}
g_hTracks[g_iPlaylistCount].PushString(sTrackPath);
g_hTrackNames[g_iPlaylistCount].PushString(sTrackName);
PrecacheSound(sTrackPath, true);
}
delete hFile;
g_iPlaylistCount++;
}
}
}
public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast) {
for (int i = 1; i <= MaxClients; i++) {
if (IsClientInGame(i) && !IsFakeClient(i) && g_iClientVolume[i] > 0) {
int plIdx = g_iClientPlaylist[i];
int size = g_hTracks[plIdx].Length;
if (size == 0) continue;
int random = GetRandomInt(0, size - 1);
char sTrack[PLATFORM_MAX_PATH], sName[128];
g_hTracks[plIdx].GetString(random, sTrack, sizeof(sTrack));
g_hTrackNames[plIdx].GetString(random, sName, sizeof(sName));
ClientCommand(i, "play *%s", sTrack);
if (cv_Display.IntValue == 1) {
PrintToChat(i, " \x04[Music]\x01 Сейчас играет: \x02%s", sName);
}
}
}
}
public Action Command_Res(int client, int args) { if (client != 0) ShowMainMenu(client); return Plugin_Handled; }
void ShowMainMenu(int client) {
Menu menu = new Menu(Handler_MainMenu);
char sTitle[128]; Format(sTitle, sizeof(sTitle), "Настройки музыки\nСтатус: %s", (g_iClientVolume[client] > 0) ? "Вкл" : "Выкл");
menu.SetTitle(sTitle);
menu.AddItem("toggle", (g_iClientVolume[client] > 0) ? "Выключить" : "Включить");
menu.AddItem("list", "Выбрать плейлист");
menu.ExitButton = true;
menu.Display(client, 20);
}
public int Handler_MainMenu(Menu menu, MenuAction action, int client, int param2) {
if (action == MenuAction_Select) {
char info[32]; menu.GetItem(param2, info, sizeof(info));
if (StrEqual(info, "toggle")) {
g_iClientVolume[client] = (g_iClientVolume[client] > 0) ? 0 : 100;
PrintToChat(client, " \x04[Music]\x01 Музыка %s", (g_iClientVolume[client] > 0) ? "\x04Включена" : "\x02Выключена");
ShowMainMenu(client);
} else if (StrEqual(info, "list")) ShowPlaylistMenu(client);
} else if (action == MenuAction_End) delete menu; return 0;
}
void ShowPlaylistMenu(int client) {
Menu menu = new Menu(Handler_Playlist);
menu.SetTitle("Выберите плейлист:");
for (int i = 0; i < g_iPlaylistCount; i++) {
char sIdx[8]; IntToString(i, sIdx, sizeof(sIdx));
menu.AddItem(sIdx, g_sPlaylistNames[i]);
}
menu.Display(client, 20);
}
public int Handler_Playlist(Menu menu, MenuAction action, int client, int param2) {
if (action == MenuAction_Select) {
char info[8]; menu.GetItem(param2, info, sizeof(info));
int idx = StringToInt(info);
g_iClientPlaylist[client] = idx;
PrintToChat(client, " \x04[Music]\x01 Плейлист: \x02%s", g_sPlaylistNames[idx]);
} else if (action == MenuAction_End) delete menu; return 0;
}
public Action Timer_Announce(Handle timer) {
PrintToChatAll(" \x04[Music]\x01 Напиши \x02!res\x01 для настройки.");
return Plugin_Continue;
}
ну всё, вы теперь гуру, можете открывать свой отдельный форум и получать хвальбы)Тестил на CSS-OB. Новый синтаксис (sm1.12), возможность выбора плейлиста, умеет выводить в чат исполнителя и трек (если предварительно указать в конфиге). Тестите
round_end_music.sp:#include <sourcemod> #include <sdktools> #pragma newdecls required #pragma semicolon 1 public Plugin myinfo = { name = "Round End Music (Manual Tags)", author = "Google Ai", version = "1" }; ConVar cv_AnnounceEvery, cv_SoundsList, cv_Display; ArrayList g_hTracks[16]; ArrayList g_hTrackNames[16]; char g_sPlaylistNames[16][64]; int g_iPlaylistCount = 0; int g_iClientVolume[MAXPLAYERS + 1]; int g_iClientPlaylist[MAXPLAYERS + 1]; public void OnPluginStart() { cv_AnnounceEvery = CreateConVar("sm_res_announceevery", "120", "Interval !res"); cv_SoundsList = CreateConVar("sm_res_soundslist", "cfg/sourcemod/rock.txt,cfg/sourcemod/rap.txt", "Playlists"); cv_Display = CreateConVar("sm_res_displaysound", "1", "Show track info"); AutoExecConfig(true, "res"); HookEvent("round_end", Event_RoundEnd); RegConsoleCmd("sm_res", Command_Res); for (int i = 0; i < 16; i++) { g_hTracks[i] = new ArrayList(PLATFORM_MAX_PATH); g_hTrackNames[i] = new ArrayList(128); } CreateTimer(cv_AnnounceEvery.FloatValue, Timer_Announce, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE); } public void OnClientPutInServer(int client) { g_iClientVolume[client] = 100; g_iClientPlaylist[client] = 0; } public void OnMapStart() { LoadAllPlaylists(); } void LoadAllPlaylists() { g_iPlaylistCount = 0; char sBuffer[1024], sParts[16][PLATFORM_MAX_PATH]; cv_SoundsList.GetString(sBuffer, sizeof(sBuffer)); int count = ExplodeString(sBuffer, ",", sParts, 16, PLATFORM_MAX_PATH); for (int i = 0; i < count; i++) { TrimString(sParts[i]); if (sParts[i][0] == '\0') continue; char sPath[PLATFORM_MAX_PATH]; BuildPath(Path_SM, sPath, sizeof(sPath), "../../%s", sParts[i]); if (g_iPlaylistCount >= 16) break; if (!FileExists(sPath)) { File hNewFile = OpenFile(sPath, "w"); if (hNewFile != null) { hNewFile.WriteLine("// Формат: путь/к/файлу.mp3 * Исполнитель - Название"); if (i == 0) hNewFile.WriteLine("ambient/music/bongo.wav * Прикольные Бонго"); else hNewFile.WriteLine("ambient/music/flamenco.wav * Испанские гитары"); delete hNewFile; } } int lastSlash = FindCharInString(sParts[i], '/', true); if (lastSlash == -1) strcopy(g_sPlaylistNames[g_iPlaylistCount], 64, sParts[i]); else strcopy(g_sPlaylistNames[g_iPlaylistCount], 64, sParts[i][lastSlash + 1]); ReplaceString(g_sPlaylistNames[g_iPlaylistCount], 64, ".txt", ""); g_hTracks[g_iPlaylistCount].Clear(); g_hTrackNames[g_iPlaylistCount].Clear(); File hFile = OpenFile(sPath, "r"); if (hFile != null) { char sLine[256]; while (hFile.ReadLine(sLine, sizeof(sLine))) { TrimString(sLine); if (sLine[0] == '\0' || sLine[0] == '/' || sLine[0] == '#') continue; char sTrackPath[PLATFORM_MAX_PATH], sTrackName[128]; int starIdx = FindCharInString(sLine, '*'); if (starIdx != -1) { strcopy(sTrackPath, (starIdx < PLATFORM_MAX_PATH) ? starIdx + 1 : PLATFORM_MAX_PATH, sLine); TrimString(sTrackPath); strcopy(sTrackName, sizeof(sTrackName), sLine[starIdx + 1]); TrimString(sTrackName); } else { strcopy(sTrackPath, sizeof(sTrackPath), sLine); int slash = FindCharInString(sTrackPath, '/', true); if (slash == -1) strcopy(sTrackName, sizeof(sTrackName), sTrackPath); else strcopy(sTrackName, sizeof(sTrackName), sTrackPath[slash + 1]); ReplaceString(sTrackName, sizeof(sTrackName), ".mp3", ""); ReplaceString(sTrackName, sizeof(sTrackName), ".wav", ""); } g_hTracks[g_iPlaylistCount].PushString(sTrackPath); g_hTrackNames[g_iPlaylistCount].PushString(sTrackName); PrecacheSound(sTrackPath, true); } delete hFile; g_iPlaylistCount++; } } } public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast) { for (int i = 1; i <= MaxClients; i++) { if (IsClientInGame(i) && !IsFakeClient(i) && g_iClientVolume[i] > 0) { int plIdx = g_iClientPlaylist[i]; int size = g_hTracks[plIdx].Length; if (size == 0) continue; int random = GetRandomInt(0, size - 1); char sTrack[PLATFORM_MAX_PATH], sName[128]; g_hTracks[plIdx].GetString(random, sTrack, sizeof(sTrack)); g_hTrackNames[plIdx].GetString(random, sName, sizeof(sName)); ClientCommand(i, "play *%s", sTrack); if (cv_Display.IntValue == 1) { PrintToChat(i, " \x04[Music]\x01 Сейчас играет: \x02%s", sName); } } } } public Action Command_Res(int client, int args) { if (client != 0) ShowMainMenu(client); return Plugin_Handled; } void ShowMainMenu(int client) { Menu menu = new Menu(Handler_MainMenu); char sTitle[128]; Format(sTitle, sizeof(sTitle), "Настройки музыки\nСтатус: %s", (g_iClientVolume[client] > 0) ? "Вкл" : "Выкл"); menu.SetTitle(sTitle); menu.AddItem("toggle", (g_iClientVolume[client] > 0) ? "Выключить" : "Включить"); menu.AddItem("list", "Выбрать плейлист"); menu.ExitButton = true; menu.Display(client, 20); } public int Handler_MainMenu(Menu menu, MenuAction action, int client, int param2) { if (action == MenuAction_Select) { char info[32]; menu.GetItem(param2, info, sizeof(info)); if (StrEqual(info, "toggle")) { g_iClientVolume[client] = (g_iClientVolume[client] > 0) ? 0 : 100; PrintToChat(client, " \x04[Music]\x01 Музыка %s", (g_iClientVolume[client] > 0) ? "\x04Включена" : "\x02Выключена"); ShowMainMenu(client); } else if (StrEqual(info, "list")) ShowPlaylistMenu(client); } else if (action == MenuAction_End) delete menu; return 0; } void ShowPlaylistMenu(int client) { Menu menu = new Menu(Handler_Playlist); menu.SetTitle("Выберите плейлист:"); for (int i = 0; i < g_iPlaylistCount; i++) { char sIdx[8]; IntToString(i, sIdx, sizeof(sIdx)); menu.AddItem(sIdx, g_sPlaylistNames[i]); } menu.Display(client, 20); } public int Handler_Playlist(Menu menu, MenuAction action, int client, int param2) { if (action == MenuAction_Select) { char info[8]; menu.GetItem(param2, info, sizeof(info)); int idx = StringToInt(info); g_iClientPlaylist[client] = idx; PrintToChat(client, " \x04[Music]\x01 Плейлист: \x02%s", g_sPlaylistNames[idx]); } else if (action == MenuAction_End) delete menu; return 0; } public Action Timer_Announce(Handle timer) { PrintToChatAll(" \x04[Music]\x01 Напиши \x02!res\x01 для настройки."); return Plugin_Continue; }
Чем обосновано установка количества плейлистов равное 16?ArrayList g_hTracks[16]; ArrayList g_hTrackNames[16]; char g_sPlaylistNames[16][64];
Ты же в курсе о лимите размера строки значения квара? Т.е. при достаточно длинных путях последние символы прописаные как значение квара в конфиге попросту обрежутся.cv_SoundsList = CreateConVar("sm_res_soundslist", "cfg/sourcemod/rock.txt,cfg/sourcemod/rap.txt", "Playlists");
Зачем вы поясняете людям,которые даже за ошибки в коде вам не скажут?Чем обосновано установка количества плейлистов равное 16?
Почему это значение каждый раз прописано числом, а не был использован дефайн? Чтобы концы искать было потруднее в случае чего?
Ты же в курсе о лимите размера строки значения квара? Т.е. при достаточно длинных путях последние символы прописаные как значение квара в конфиге попросту обрежутся.
Кроме того лучше заводить отдельную папочку для конфигов плагина, если он использует их сразу несколько и задавать её отдельно (и чтобы не дублировать путь к ней в пути конфигов). Хотя бы для того чтобы не случалось коллизий в названии файлов у разных плагинов. Ну и чтобы срача в папке конфигов было поменьше.
Т.е. лучше задавать путь к папке для конфигов, а плагин пусть сам смотрит какие файлы конфигов там есть и читает их без указывания пути к каждому файлу. Если конфиги используются не одного типа, то можно делать обязательный префикс в имени файла конфига и плагин пусть проверяет его наличие.
Ну и одно из любимых мной косяков: создание массивов внутри циклов.
Дальше уже не вникал. Может ещё косяки в коде имеются.
До нормального кодера чатгопоте ещё долго учиться. А пытающийся писать с её помощью должен как минимум сам хорошо знать кучу нюансов.
Нет .@-=|УЧЕНИК|=-, может в процессе Искусственный Идиот чему-то полезному научит натурального?![]()