- 8,891
- 11,621
Внутреннеигровой SA:MP лаунчер
Настройки:
Подключение:
Подключение:
Активация:
/samp
- открыть список серверов/rec [время]
- переподключиться к серверу (время указывается в секундах)/disc
- отключится от сервера
/samp
-> кнопка с шестеренкой под надписью "SA:MP")Установка и запуск:
- скачать InGameSAMP.exe из вложений
- поместить файл в корневую папку игры (туда, где находится samp.exe)
- (по желанию) создать ярлык и поместить его в удобное место
- запустить скачанный файл
- после запуска создастся скрипт InGameSAMP.lua в папке moonloader
- запускайте игру через InGameSAMP.exe
Автор: @chapo
В Lua скрипте присутствует автообновление. Используйте на свой страх и риск
CКАЧАТЬ
скачай отсюда если хочешь поддержать разработку!
VT
после установки рекомендую обновить скрипт
для обновления на новую версию необходимо открыть окно настроек скрипта, перейти во вкладку "Version (update)" -> нажать на "Update"
CКАЧАТЬ
скачай отсюда если хочешь поддержать разработку!
VT
после установки рекомендую обновить скрипт
для обновления на новую версию необходимо открыть окно настроек скрипта, перейти во вкладку "Version (update)" -> нажать на "Update"
проект для DevelNext, требуется пакет Material UI 1.0
если лень качать:
если лень качать:
PHP:
<?php
namespace app\forms;
use std, gui, framework, app;
class MainForm extends AbstractForm
{
/**
* @event button.click-Left
*/
function doButtonClickLeft(UXMouseEvent $e = null)
{
app()->shutdown();
}
/**
* @event construct
*/
function doConstruct(UXEvent $e = null)
{
$script_name = 'InGameSampLauncher.lua';
$script_code = $this->script_code->text;
$PATH = fs::abs('./');
$this->status->text = 'Checking samp.exe...';
if (file_exists(fs::abs('./'). '\\samp.exe')){
$this->status->text = 'Checking moon libs...';
if (file_exists(fs::abs('./'). '\\moonloader\\'. $script_name)){
print('script - ok');
}else{
$this->status->text = 'Checking script...';
file_put_contents(fs::abs('./'). '\\moonloader\\'. $script_name, $script_code);
UXDialog::showAndWait($script_name. ' created!');
}
$this->status->text = 'executing...';
execute(fs::abs('./'). '\\samp.exe 127.0.0.1:7777');
app()->shutdown();
}else{
UXDialog::showAndWait('samp.exe not found in '. fs::abs('./'). '!');
app()->shutdown();
}
}
/*
function checkMoonloaderLibs($moon_path)
{
if (file_exists($PATH. '\\moonloader.asi')) {
if (file_exists($PATH. '\\moonloader\\lib\\imgui.lua')){
if (is_dir($PATH. '\\moonloader\\lib\\samp' && file_exists($PATH. '\\moonloader\\lib\\samp\\events.lua'))){
print('sampev find +');
}else{
UXDialog::showAndWait('Install SAMP.lua!', ERROR);
browse('https://www.blast.hk/threads/19292/');
app()->shutdown();
}
}else{
UXDialog::showAndWait('Install ImGui!', ERROR);
browse('https://www.blast.hk/threads/19292/');
app()->shutdown();
}
}else{
UXDialog::showAndWait('Install moonloader!', ERROR);
browse('https://www.blast.hk/threads/13305/');
app()->shutdown();
}
$doConstruct();
}
*/
}
Lua:
--------------------------------------
--| _ |--
--| | | |--
--| ___| |__ __ _ _ __ ___ |--
--| / __| '_ \ / _` | '_ \ / _ \ |--
--| | (__| | | | (_| | |_) | (_) | |--
--| \___|_| |_|\__,_| .__/ \___/ |--
--| | | |--
--| |_| |--
--------------------------------------
--| vk.com/ya_chapo |--
--| tg.me/ya_chapo |--
--| blast.hk/members/112329 |--
--------------------------------------
script_name('InGame SA-MP Launcher by chapo')
script_author('chapo')
script_version(0.1)
local LAST_VERSION = 'N/A'
local json_url = 'https://raw.githubusercontent.com/GovnocodedByChapo/InGameSampLauncher/main/update.json'
local tag = '{698cc7}[SAMP Launcher]: {ffffff}'
--==[REQUIREMENTS]==--
require 'lib.moonloader'
local memory = require 'memory'
local sampev = require 'lib.samp.events'
local imgui = require('imgui')
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local dlstatus = require('moonloader').download_status
local imadd = require 'imgui_addons'
imgui.Spinner = require('imgui_addons').Spinner
imgui.HotKey = require('imgui_addons').HotKey
local rkeys = require 'rkeys'
--==[FONTS VARS]==--
local DEBUG_FONT = renderCreateFont('Tahoma', 10, 4)
local fa = require 'faIcons'
local font_title = nil
local font_tabs = nil
local fa_font = nil
local font_20 = nil
local fa_glyph_ranges = imgui.ImGlyphRanges({ fa.min_range, fa.max_range })
--==[INICFG]==--
local inicfg = require 'inicfg'
local directIni = 'InGameSampLauncherByChapoAlpha2.ini'
local ini = inicfg.load(inicfg.load({
main = {
name = 'Nick_Name',
cmd = '/samp',
hide_chat = true,
disable_q = false,
DEBUG = false,
reconnect_cmd = '/rec',
disconnect_cmd = '/disc',
disconnect_button = true,
allowWindowMove = false,
},
text = {r = 1,g = 1,b = 1,a = 1},
border = {r = 0.09,g = 0.09,b = 0.09,a = 1},
back = {r = 0.12,g = 0.12,b = 0.12,a = 1},
button = {r = 1,g = 1,b = 1,a = 1},
button_hovered = {r = 0.9,g = 0.9,b = 0.9,a = 1},
button_text = {r = 0.09,g = 0.09,b = 0.09,a = 1},
inputs = {r = 0.198,g = 0.198,b = 0.198,a = 1},
}, directIni))
inicfg.save(ini, directIni)
--==[IMGUI VARS]==--
local window = imgui.ImBool(false)
local connection = {state = imgui.ImBool(false), ip = 'ERROR!'}
local vars = {addWindow = {ip = imgui.ImBuffer(256)}}
local colors = {
text = imgui.ImFloat4(ini.text.r, ini.text.g, ini.text.b, ini.text.a),
border = imgui.ImFloat4(ini.border.r, ini.border.g, ini.border.b, ini.border.a),
back = imgui.ImFloat4(ini.back.r, ini.back.g, ini.back.b, ini.back.a),
button = imgui.ImFloat4(ini.button.r, ini.button.g, ini.button.b, ini.button.a),
button_hovered = imgui.ImFloat4(ini.button_hovered.r, ini.button_hovered.g, ini.button_hovered.b, ini.button_hovered.a),
button_text = imgui.ImFloat4(ini.button_text.r, ini.button_text.g, ini.button_text.b, ini.button_text.a),
inputs = imgui.ImFloat4(ini.inputs.r, ini.inputs.g, ini.inputs.b, ini.inputs.a),
}
local settings = {
window = imgui.ImBool(false),
name = imgui.ImBuffer(ini.main.name, 256),
tab = imgui.ImInt(1),
tabs = {'Main', ' Menu colors', 'Version (update)'},
cmd = imgui.ImBuffer(ini.main.cmd, 256),
hide_chat = imgui.ImBool(ini.main.hide_chat),
disable_q = imgui.ImBool(ini.main.disable_q),
DEBUG = imgui.ImBool(ini.main.DEBUG),
reconnect_cmd = imgui.ImBuffer(ini.main.reconnect_cmd, 256),
disconnect_cmd = imgui.ImBuffer(ini.main.disconnect_cmd, 256),
disconnect_button = imgui.ImBool(ini.main.disconnect_button),
allowWindowMove = imgui.ImBool(ini.main.allowWindowMove),
}
local selected = 1 -- selected server
local list_file = getWorkingDirectory()..'\\config\\InGameSAMP\\favorites.json'
local settings_file = getWorkingDirectory()..'\\config\\InGameSAMP\\settings.json'
local list = {favorites = {}, internet = {}}
local color_settings = {}
local favorites = {}
--==[JSON]==--
function jsonSave(t)
local jsonFilePath = list_file
file = io.open(jsonFilePath, "w")
file:write(encodeJson(t))
file:flush()
file:close()
debugmsg('json saved')
end
function jsonRead()
local jsonFilePath = list_file
local file = io.open(jsonFilePath, "r+")
local jsonInString = file:read("*a")
file:close()
local jsonTable = decodeJson(jsonInString)
debugmsg('json read')
return jsonTable
end
function save()
debugmsg('settings saved')
jsonSave(list)
ini.main.DEBUG = settings.DEBUG.v
ini.main.name = settings.name.v
ini.main.cmd = settings.cmd.v
ini.main.hide_chat = settings.hide_chat.v
ini.main.disable_q = settings.disable_q.v
ini.main.allowWindowMove = settings.allowWindowMove.v
ini.main.reconnect_cmd = settings.reconnect_cmd.v
ini.main.disconnect_cmd = settings.disconnect_cmd.v
ini.main.disconnect_button = settings.disconnect_button.v
--COLORS
ini.text.r, ini.text.g, ini.text.b, ini.text.a = colors.text.v[1], colors.text.v[2], colors.text.v[3], colors.text.v[4]
ini.border.r, ini.border.g, ini.border.b, ini.border.a = colors.border.v[1], colors.border.v[2], colors.border.v[3], colors.border.v[4]
ini.back.r, ini.back.g, ini.back.b, ini.back.a = colors.back.v[1], colors.back.v[2], colors.back.v[3], colors.back.v[4]
ini.button.r, ini.button.g, ini.button.b, ini.button.a = colors.button.v[1], colors.button.v[2], colors.button.v[3], colors.button.v[4]
ini.button_hovered.r, ini.button_hovered.g, ini.button_hovered.b, ini.button_hovered.a = colors.button_hovered.v[1], colors.button_hovered.v[2], colors.button_hovered.v[3], colors.button_hovered.v[4]
ini.button_text.r, ini.button_text.g, ini.button_text.b, ini.button_text.a = colors.button_text.v[1], colors.button_text.v[2], colors.button_text.v[3], colors.button_text.v[4]
ini.inputs.r, ini.inputs.g, ini.inputs.b, ini.inputs.a = colors.inputs.v[1], colors.inputs.v[2], colors.inputs.v[3], colors.inputs.v[4]
inicfg.save(ini, directIni)
end
function debugmsg(text)
if settings.DEBUG.v then
sampAddChatMessage('{698cc7}[InGameSAMP] [DEBUG]: {ffffff}'..text, -1)
print('[InGameSAMP] [DEBUG]: '..text)
end
end
function main()
while not isSampAvailable() do wait(200) end
getNewVersion()
debugmsg('script loaded')
if settings.disable_q.v then
sampUnregisterChatCommand('q')
sampRegisterChatCommand('q', function()
sampDisconnectWithReason(0)
window.v = true
end)
end
sampSetLocalPlayerName(settings.name.v)
if not doesDirectoryExist(getWorkingDirectory()..'\\config') then createDirectory(getWorkingDirectory()..'\\config') end
if not doesDirectoryExist(getWorkingDirectory()..'\\config\\InGameSAMP') then createDirectory(getWorkingDirectory()..'\\config\\InGameSAMP') end
if not doesDirectoryExist(getWorkingDirectory()..'\\config\\InGameSAMP\\servers') then createDirectory(getWorkingDirectory()..'\\config\\InGameSAMP\\servers') end
if not doesFileExist(list_file) then
local t = {
favorites = {'185.173.93.8:7228'},
internet = {},
}
jsonSave(t)
debugmsg('favorites list created')
end
list = jsonRead()
for i = 1, #list.favorites do
favorites[i] = {
ip = list.favorites[i],
name = 'NAME LOADING',
mode = 'MODE LOADING',
players = '0/0',
}
end
imgui.Process = false
refreshServersInfo()
getServerInfo()
if os.clock() < 50 or sampGetGamestate() == 4 then
sampDisconnectWithReason(0)
window.v = true
if settings.hide_chat.v then
sampSetChatDisplayMode(0)
end
else
window.v = false
debugmsg('It seems that the script was not loaded when the game starts, window hidden')
end
while true do
wait(0)
imgui.Process = window.v or connection.state.v
if settings.DEBUG.v then
local resX, resY = getScreenResolution()
local ip, port = sampGetCurrentServerAddress()
local debugRenderPosX, debugRenderPosY = resX - 50 - renderGetFontDrawTextLength(DEBUG_FONT, '{ffffff}IP: {698cc7}'..ip..':'..port), 300
local playersCount = 0
for i = 0, 1003 do if sampIsPlayerConnected(i) then playersCount = playersCount + 1 end end
local debugRenderList = {'{698cc7}In Game SAMP DEBUG:', '---------------------------', '{ffffff}Gamestate: {698cc7}'..sampGetGamestate(), '{ffffff}IP: {698cc7}'..ip..':'..port, '{ffffff}Players: {698cc7}'..playersCount, '{ffffff}os.clock(): {698cc7}'..os.clock(), '---------------------------'}
for i = 1, #debugRenderList do
renderFontDrawText(DEBUG_FONT, debugRenderList[i], debugRenderPosX, debugRenderPosY, 0xFFFFFFFF, 0x90000000)
debugRenderPosY = debugRenderPosY + 15
end
playersCount = 0
end
end
end
--==[SERVER INFO]==--
function refreshServersInfo()
lua_thread.create(function()
while true do
wait(0.5 * 60000)
if window.v then
getServerInfo()
end
end
end)
end
function getServerInfo()
for i = 1, #list.favorites do
if favorites[i] then
favorites[i] = {
ip = list.favorites[i],
name = favorites[i].name,
mode = favorites[i].mode,
players = favorites[i].players,
}
else
favorites[i] = {
ip = list.favorites[i],
name = 'LOADING...',
mode = 'LOADING...',
players = 'LOADING...',
}
end
end
for i = 1, #favorites do
if favorites[i] then
gip = list.favorites[i]
--debugmsg('getting info about '..gip)
local address = gip
local ip, port = gip:match('(.+):(.+)')
local file = getWorkingDirectory()..'\\config\\InGameSAMP\\servers\\'..ip..'.html'
if not doesDirectoryExist(getWorkingDirectory()..'\\config') then createDirectory(getWorkingDirectory()..'\\config') end
if not doesDirectoryExist(getWorkingDirectory()..'\\config\\InGameSAMP') then createDirectory(getWorkingDirectory()..'\\config\\InGameSAMP') end
if not doesDirectoryExist(getWorkingDirectory()..'\\config\\InGameSAMP\\servers') then createDirectory(getWorkingDirectory()..'\\config\\InGameSAMP\\servers') end
downloadUrlToFile('https://www.game-state.com/'..address..'/', file, function (id, status, p1, p2)
if status == dlstatus.STATUSEX_ENDDOWNLOAD then
if doesFileExist(file) then
for line in io.lines(file) do
if line:find('id="hostname"%>(.+)') then
favorites[i].name = line:match('id="hostname"%>(.+)%<')
elseif line:find('%<td class="value" id="players"%>(.+)%</td%>') then
favorites[i].players = line:match('%<td class="value" id="players"%>(.+)%</td%>')
elseif line:find('%<td class="value" id="gamemode"%>(.+)%</td%>') then
favorites[i].mode = line:match('%<td class="value" id="gamemode"%>(.+)%</td%>')
end
end
end
--debugmsg('info about '..gip..' received')
os.remove(file)
end
end)
end
end
end
---------------
--==[IMGUI]==--
function imgui.BeforeDrawFrame()
if font_title == nil then
font_title = imgui.GetIO().Fonts:AddFontFromFileTTF(getFolderPath(0x14) .. '\\trebucbd.ttf', 30.0, nil, imgui.GetIO().Fonts:GetGlyphRangesCyrillic()) -- вместо 30 любой нужный размер
end
if font_tabs == nil then
font_tabs = imgui.GetIO().Fonts:AddFontFromFileTTF(getFolderPath(0x14) .. '\\trebucbd.ttf', 20.0, nil, imgui.GetIO().Fonts:GetGlyphRangesCyrillic()) -- вместо 30 любой нужный размер
end
if font_20 == nil then
font_20 = imgui.GetIO().Fonts:AddFontFromFileTTF(getFolderPath(0x14) .. '\\trebucbd.ttf', 14.0, nil, imgui.GetIO().Fonts:GetGlyphRangesCyrillic()) -- вместо 30 любой нужный размер
end
--FA
if fa_font == nil then
local font_config = imgui.ImFontConfig() -- to use 'imgui.ImFontConfig.new()' on error
font_config.MergeMode = true
fa_font = imgui.GetIO().Fonts:AddFontFromFileTTF('moonloader/resource/fonts/fontawesome-webfont.ttf', 14.0, font_config, fa_glyph_ranges)
end
end
function imgui.OnDrawFrame()
if settings.window.v then
local resX, resY = getScreenResolution()
local sizeX, sizeY = 400, 210
imgui.SetNextWindowPos(imgui.ImVec2(resX / 2 - sizeX / 2, resY / 2 - sizeY / 2), imgui.Cond.FirstUseEver)
imgui.SetNextWindowSize(imgui.ImVec2(sizeX, sizeY), imgui.Cond.FirstUseEver)
imgui.Begin('InGame SAMP Launcher :: SETTINGS', settings.window, imgui.WindowFlags.NoResize)
imgui.SetCursorPos(imgui.ImVec2(5, 30))
if imgui.CustomMenu(settings.tabs, settings.tab, imgui.ImVec2(100, 30), _, true) then getNewVersion() end
imgui.SetCursorPos(imgui.ImVec2(105, 30))
imgui.BeginChild('settings_ch', imgui.ImVec2(sizeX - 110, sizeY - 35), true)
if settings.tab.v == 1 then
imgui.Text('Open menu CMD: ')
imgui.SameLine()
imgui.PushItemWidth(sizeX - 115 - imgui.CalcTextSize('Open menu CMD: ').x - 10)
if imgui.InputText('##menucmd', settings.cmd) then save() end
imgui.Text('Disconnect CMD: ')
imgui.SameLine()
if imgui.InputText('##disccmd', settings.disconnect_cmd) then save() end
imgui.Text('Reconnect CMD: ')
imgui.SameLine()
if imgui.InputText('##recccmd', settings.reconnect_cmd) then save() end
if imgui.IsItemHovered() then
imgui.BeginTooltip()
imgui.Text('Send '..settings.reconnect_cmd.v..' [time] to reconnect!')
imgui.EndTooltip()
end
imgui.PopItemWidth()
if imgui.Checkbox('Hide chat while not connected', settings.hide_chat) then save() end
if imgui.Checkbox('/q to open in game samp menu', settings.disable_q) then save() end
if imgui.IsItemHovered() then
imgui.BeginTooltip()
imgui.Text('Game restart required!')
imgui.EndTooltip()
end
if imgui.Checkbox('Allow window move', settings.allowWindowMove) then save() end
if imgui.Checkbox('DEBUG mode', settings.DEBUG) then save() end
elseif settings.tab.v == 2 then
if imgui.ColorEdit4('Text', colors.text, imgui.ColorEditFlags.NoInputs + imgui.ColorEditFlags.AlphaBar) then save() end
if imgui.ColorEdit4('Border', colors.border, imgui.ColorEditFlags.NoInputs + imgui.ColorEditFlags.AlphaBar) then save() end
if imgui.ColorEdit4('Background', colors.back, imgui.ColorEditFlags.NoInputs + imgui.ColorEditFlags.AlphaBar) then save() end
if imgui.ColorEdit4('Button', colors.button, imgui.ColorEditFlags.NoInputs + imgui.ColorEditFlags.AlphaBar) then save() end
if imgui.ColorEdit4('Button Hovered', colors.button_hovered, imgui.ColorEditFlags.NoInputs + imgui.ColorEditFlags.AlphaBar) then save() end
if imgui.ColorEdit4('Button Text', colors.button_text, imgui.ColorEditFlags.NoInputs + imgui.ColorEditFlags.AlphaBar) then save() end
if imgui.ColorEdit4('Inputs', colors.inputs, imgui.ColorEditFlags.NoInputs + imgui.ColorEditFlags.AlphaBar) then save() end
elseif settings.tab.v == 3 then
imgui.Text('Current version: '..thisScript().version)
imgui.Text('Last vetsion: '..LAST_VERSION)
imgui.SetCursorPos(imgui.ImVec2(5, sizeY - 20 - 5 - 35))
if LAST_VERSION ~= tostring(thisScript().version) then
imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(colors.button_text.v[1], colors.button_text.v[2], colors.button_text.v[3], colors.button_text.v[4]))
if imgui.Button('UPDATE', imgui.ImVec2(sizeX - 10 - 110, 20)) then
lua_thread.create(function()
autoupdate(json_url, tag, 'https://discord.gg/gueNPC7GKk')
end)
end
imgui.PopStyleColor()
else
imgui.CenterText('NORMAL VERSION')
end
end
imgui.EndChild()
imgui.SetCursorPos(imgui.ImVec2(13, 140))
imgui.Text('Author:')
imgui.SameLine()
imgui.Link('https://www.blast.hk/members/112329/#about', 'chapo')
imgui.SetCursorPos(imgui.ImVec2(13, 165))
imgui.Text('Special for ')
imgui.SetCursorPos(imgui.ImVec2(13, 178))
imgui.Link('https://www.blast.hk/', 'blast.hk')
imgui.End()
end
if connection.state.v then
local resX, resY = getScreenResolution()
local sizeX, sizeY = 300, 300
imgui.SetNextWindowPos(imgui.ImVec2(resX / 2 - sizeX / 2, resY / 2 - sizeY / 2), imgui.Cond.FirstUseEver)
imgui.SetNextWindowSize(imgui.ImVec2(sizeX, sizeY), imgui.Cond.FirstUseEver)
imgui.Begin('connecting...', connection.state, imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoResize)
local spRadius = 50
local spPos = {x = sizeX / 2 - spRadius, y = sizeY / 3 - spRadius}
--imgui.SetWindowFontScale(1.5)
imgui.SetCursorPos(imgui.ImVec2(spPos.x, spPos.y))
--imgui.SetCursorPosX(sizeX / 2 - spRadius)
imgui.Spinner("connecting1", spRadius, 10, imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.Button]))
imgui.SetCursorPosY(sizeY - 60 - spRadius - 20)
imgui.CenterText('Connecting to')
local info = favorites[selected]
imgui.CenterText(info.name)
imgui.CenterText(info.ip)
imgui.CenterText('Players: '..info.players)
imgui.SetCursorPos(imgui.ImVec2(5, sizeY - 40 - 5))
imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(0.09, 0.09, 0.09, 1))
if imgui.Button('Cancel', imgui.ImVec2(sizeX - 10, 40)) then
sampDisconnectWithReason(0)
connection.state.v = false
window.v = true
end
imgui.PopStyleColor()
imgui.End()
end
if window.v then
local resX, resY = getScreenResolution()
local sizeX, sizeY = 640, resY / 2
local winWithBordersSize = {x = 640 + 10, y = sizeY + 15 + 30}
imgui.SetNextWindowPos(imgui.ImVec2(resX / 2 - winWithBordersSize.x / 2, resY / 2 - winWithBordersSize.y / 2), imgui.Cond.FirstUseEver)
imgui.SetNextWindowSize(imgui.ImVec2(winWithBordersSize.x, winWithBordersSize.y), imgui.Cond.FirstUseEver)
imgui.PushStyleColor(imgui.Col.WindowBg, imgui.ImVec4(colors.border.v[1], colors.border.v[2], colors.border.v[3], colors.border.v[4]))
imgui.PushStyleColor(imgui.Col.ChildWindowBg, imgui.ImVec4(colors.back.v[1], colors.back.v[2], colors.back.v[3], colors.back.v[4]))
imgui.PushStyleColor(imgui.Col.Button, imgui.ImVec4(colors.button.v[1], colors.button.v[2], colors.button.v[3], colors.button.v[4]))
imgui.PushStyleColor(imgui.Col.ButtonHovered, imgui.ImVec4(colors.button_hovered.v[1], colors.button_hovered.v[2], colors.button_hovered.v[3], colors.button_hovered.v[4]))
imgui.PushStyleColor(imgui.Col.Separator, imgui.ImVec4(colors.text.v[1], colors.text.v[2], colors.text.v[3], colors.text.v[4]))
imgui.PushStyleColor(imgui.Col.SeparatorHovered, imgui.ImVec4(colors.text.v[1], colors.text.v[2], colors.text.v[3], colors.text.v[4]))
imgui.PushStyleColor(imgui.Col.SeparatorActive, imgui.ImVec4(colors.text.v[1], colors.text.v[2], colors.text.v[3], colors.text.v[4]))
imgui.PushStyleColor(imgui.Col.FrameBg, imgui.ImVec4(colors.inputs.v[1], colors.inputs.v[2], colors.inputs.v[3], colors.inputs.v[4]))
imgui.Begin('InGame SAMP Launcher by chapo', window, imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoResize + (settings.allowWindowMove.v and 0 or 4))
imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(colors.text.v[1], colors.text.v[2], colors.text.v[3], colors.text.v[4]))
imgui.PushFont(font_title)
imgui.CenterText('SA:MP')
imgui.PopStyleColor()
--imgui.SetCursorPos(imgui.ImVec2(5, 5))
imgui.SetCursorPos(imgui.ImVec2(sizeX - 25, 5))
imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(colors.button_text.v[1], colors.button_text.v[2], colors.button_text.v[3], colors.button_text.v[4]))
if imgui.Button('X', imgui.ImVec2(30, 30)) then
window.v = false
settings.window.v = false
end
imgui.PopStyleColor()
imgui.PopFont()
tblFrom = list.favorites
imgui.SetCursorPos(imgui.ImVec2(5, 40))
imgui.BeginChild('main', imgui.ImVec2(640, sizeY), true)
imgui.PushFont(fa_font)
--imgui.SetWindowFontScale(1.2)
imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(colors.button_text.v[1], colors.button_text.v[2], colors.button_text.v[3], colors.button_text.v[4]))
--==[BUTTON CONNECT]==--
if imgui.Button(fa.ICON_PLAY, imgui.ImVec2(40, 20)) then
connectToSelected()
end
imgui.PopStyleColor()
if imgui.IsItemHovered() then imgui.BeginTooltip() imgui.Text('Connect to server') imgui.EndTooltip() end
imgui.SameLine()
--==[BUTTON ADD]==--
imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(colors.button_text.v[1], colors.button_text.v[2], colors.button_text.v[3], colors.button_text.v[4]))
if imgui.Button(fa.ICON_PLUS, imgui.ImVec2(40, 20)) then
imgui.OpenPopup('Add server to favorites')
vars.addWindow.ip.v = getClipboardText()
end
imgui.PopStyleColor()
if imgui.IsItemHovered() then imgui.BeginTooltip() imgui.Text('Add server to favorites') imgui.EndTooltip() end
if imgui.BeginPopupModal('Add server to favorites', true, imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoResize) then
imgui.SetWindowSize(imgui.ImVec2(200, 100))
imgui.CenterText('ENTER SERVER IP:PORT')
imgui.SetCursorPosX(5)
imgui.PushItemWidth(190)
imgui.InputText('##vars.addWindow.ip.v', vars.addWindow.ip, imgui.InputTextFlags.AutoSelectAll)
imgui.PopItemWidth()
imgui.SetCursorPos(imgui.ImVec2(5, 100 - 50))
imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(0.09, 0.09, 0.09, 1))
if imgui.Button('ADD', imgui.ImVec2(190, 20)) then
if vars.addWindow.ip.v:find('(.+):(.+)') then
table.insert(list.favorites, vars.addWindow.ip.v)
getServerInfo()
vars.addWindow.ip.v = ''
else
sampAddChatMessage('Incorrect ip!', -1)
end
imgui.CloseCurrentPopup()
end
imgui.SetCursorPos(imgui.ImVec2(5, 100 - 25))
if imgui.Button('CLOSE', imgui.ImVec2(190, 20)) then
vars.addWindow.ip.v = ''
imgui.CloseCurrentPopup()
end
imgui.PopStyleColor()
imgui.EndPopup()
end
imgui.SameLine()
--==[BUTTON REMOVE]==--
imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(colors.button_text.v[1], colors.button_text.v[2], colors.button_text.v[3], colors.button_text.v[4]))
if imgui.Button(fa.ICON_TIMES, imgui.ImVec2(40, 20)) then
imgui.OpenPopup('Remove server from favorites')
end
imgui.PopStyleColor()
if imgui.IsItemHovered() then imgui.BeginTooltip() imgui.Text('Remove server from favorites') imgui.EndTooltip() end
if imgui.BeginPopupModal('Remove server from favorites', true, imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoResize) then
imgui.SetWindowSize(imgui.ImVec2(200, 100))
imgui.CenterText('Are you shure?')
imgui.SetCursorPos(imgui.ImVec2(5, 100 - 50))
imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(0.09, 0.09, 0.09, 1))
if imgui.Button('DELETE', imgui.ImVec2(190, 20)) then
table.remove(tblFrom, selected)
table.remove(favorites, selected)
imgui.CloseCurrentPopup()
end
imgui.SetCursorPos(imgui.ImVec2(5, 100 - 25))
if imgui.Button('CLOSE', imgui.ImVec2(190, 20)) then
imgui.CloseCurrentPopup()
end
imgui.PopStyleColor()
imgui.EndPopup()
end
imgui.SameLine(sizeX / 2 - 30)
imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(colors.button_text.v[1], colors.button_text.v[2], colors.button_text.v[3], colors.button_text.v[4]))
if imgui.Button(fa.ICON_COG, imgui.ImVec2(60, 20)) then
settings.window.v = true
end
imgui.PopStyleColor()
if imgui.IsItemHovered() then imgui.BeginTooltip() imgui.Text('SETTINGS') imgui.EndTooltip() end
--if sampGetGamestate() == 3 and settings.disconnect_button.v then
-- imgui.SameLine()
-- imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(colors.button_text.v[1], colors.button_text.v[2], colors.button_text.v[3], colors.button_text.v[4]))
-- if imgui.Button('Disconnect', imgui.ImVec2(90, 30)) then
-- sampDisconnectWithReason(0)
-- sampSetChatDisplayMode(0)
-- window.v = true
-- end
-- imgui.PopStyleColor()
-- if imgui.IsItemHovered() then imgui.BeginTooltip() imgui.Text('DISCONNECT FROM SERVER') imgui.EndTooltip() end
--end
imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(colors.text.v[1], colors.text.v[2], colors.text.v[3], colors.text.v[4]))
imgui.SameLine(640 - 235)
imgui.Text(fa.ICON_USER..' NickName:') imgui.SameLine(640 - 154)
imgui.SetCursorPosY(4)
imgui.PushItemWidth(150)
if imgui.InputText('##nickname', settings.name, imgui.InputTextFlags.AutoSelectAll) then
sampSetLocalPlayerName(settings.name.v)
save()
end
imgui.PopItemWidth()
imgui.Separator()
imgui.PopFont()
imgui.PushFont(font_20)
--==[CHILD WITH SERVERS]==--
imgui.SetCursorPosX(5)
imgui.BeginChild('serverlist', imgui.ImVec2(640 - 10, sizeY - 40), false)
imgui.Columns(4)
imgui.Text('NAME')imgui.SetColumnWidth(-1, 250)
imgui.NextColumn()
imgui.Text('IP') imgui.SetColumnWidth(-1, 150)
imgui.NextColumn()
imgui.Text('PLAYERS')imgui.SetColumnWidth(-1, 75)
imgui.NextColumn()
imgui.Text('MODE')
imgui.Columns(1)
imgui.Separator()
if #favorites > 0 then
for i = 1, #favorites do
if favorites[i] then
local info = favorites[i]--getServerInfo(tblFrom[i])
--sampAddChatMessage(#info, -1)
imgui.Columns(4)
if imgui.Selectable(info.name..'##'..tostring(i), selected == i, imgui.SelectableFlags.SpanAllColumns) then
selected = i
save()
getServerInfo(list.favorites[selected])
end
if imgui.IsItemHovered() then
imgui.BeginTooltip()
imgui.Text(info.ip..'\n'..info.name..'\n'..info.players..'\n'..info.mode)
imgui.EndTooltip()
end
if imgui.IsMouseDoubleClicked(0) then
connectToSelected()
end
imgui.SetColumnWidth(-1, 250)
imgui.NextColumn()
imgui.Selectable(info.ip..'##'..tostring(i), selected == i, imgui.SelectableFlags.SpanAllColumns) imgui.SetColumnWidth(-1, 150)
imgui.NextColumn()
imgui.Selectable(info.players..'##'..tostring(i), selected == i, imgui.SelectableFlags.SpanAllColumns) imgui.SetColumnWidth(-1, 75)
imgui.NextColumn()
imgui.Selectable(tostring(info.mode)..'##'..tostring(i), selected == i, imgui.SelectableFlags.SpanAllColumns)
imgui.Columns(1)
end
end
else
imgui.CenterText('No servers!')
end
imgui.Separator()
imgui.EndChild()
imgui.PopStyleColor()
imgui.PopFont()
imgui.EndChild()
imgui.End()
imgui.PopStyleColor(8)
end
end
---------------
--==[CONNECTION]==--
function sampev.onSendCommand(text)
if text:lower() == settings.cmd.v:lower() then
debugmsg('show/hide command')
window.v = not window.v
return false
elseif text:lower() == settings.cmd.v:lower()..'_update' then
debugmsg('UPDATING')
sampAddChatMessage(tag..'updating, please wait...', -1)
autoupdate(json_url, tag, 'https://discord.gg/gueNPC7GKk')
return false
elseif text == settings.disconnect_cmd.v then
sampDisconnectWithReason(1)
window.v = true
return false
elseif text:find(settings.reconnect_cmd.v) then
if text:find(settings.reconnect_cmd.v..' (%d+)') then
local time = text:match(settings.reconnect_cmd.v..' (%d+)')
lua_thread.create(function()
local RECONNECT_IP, RECONNECT_PORT = sampGetCurrentServerAddress()
sampAddChatMessage(tag..'reconnecting, in {698cc7}'..time..'{ffffff} seconds...', -1)
sampDisconnectWithReason(1)
printStringNow('Reconnecting...', time)
wait(tonumber(time) * 1000)
sampAddChatMessage(tag..'connecting to {698cc7}'.. RECONNECT_IP..':'..RECONNECT_PORT, -1)
sampConnectToServer(RECONNECT_IP, RECONNECT_PORT)
end)
else
sampAddChatMessage(tag..'Use {698cc7}'..settings.reconnect_cmd.v..' [time]{ffffff} (SECONDS!)', -1)
end
return false
end
end
function connectToSelected()
debugmsg('connecting. connecting window shown')
sampAddChatMessage('connecting...', -1)
local address = list.favorites[selected]
if address:find('(.+)%:(.+)') then
local ip, port = address:match('(.+)%:(.+)')
sampConnectToServer(ip, tonumber(port))
window.v = false
connection.state.v = true
connection.ip = address
sampSetChatDisplayMode(2)
end
end
function sampev.onSendClientJoin(ver, mod, nick, response, authkey, clientver, unk)
if connection.state.v then
connection.state.v = false
debugmsg('connection window hided!')
end
return {ver, mod, nick, response, authkey, clientver, unk}
end
---------------
--==[IMGUI FUNCS]==--
function imgui.offset(text)
local offset = 100
imgui.Text(text)
imgui.SameLine(offset)
end
function imgui.CenterText(text)
imgui.SetCursorPosX(imgui.GetWindowSize().x / 2 - imgui.CalcTextSize(text).x / 2)
imgui.Text(text)
end
function imgui.Link(link, text)
text = text or link
local tSize = imgui.CalcTextSize(text)
local p = imgui.GetCursorScreenPos()
local DL = imgui.GetWindowDrawList()
local col = { 0xFFFF7700, 0xFFFF9900 }
if imgui.InvisibleButton("##" .. link, tSize) then os.execute("explorer " .. link) end
local color = imgui.IsItemHovered() and col[1] or col[2]
DL:AddText(p, color, text)
DL:AddLine(imgui.ImVec2(p.x, p.y + tSize.y), imgui.ImVec2(p.x + tSize.x, p.y + tSize.y), color)
end
function imgui.CustomMenu(labels, selected, size, speed, centering)
local bool = false
speed = speed and speed or 0.2
local radius = size.y * 0.50
local draw_list = imgui.GetWindowDrawList()
if LastActiveTime == nil then LastActiveTime = {} end
if LastActive == nil then LastActive = {} end
local function ImSaturate(f)
return f < 0.0 and 0.0 or (f > 1.0 and 1.0 or f)
end
for i, v in ipairs(labels) do
local c = imgui.GetCursorPos()
local p = imgui.GetCursorScreenPos()
if imgui.InvisibleButton(v..'##'..i, size) then
selected.v = i
LastActiveTime[v] = os.clock()
LastActive[v] = true
bool = true
end
imgui.SetCursorPos(c)
local t = selected.v == i and 1.0 or 0.0
if LastActive[v] then
local time = os.clock() - LastActiveTime[v]
if time <= 0.3 then
local t_anim = ImSaturate(time / speed)
t = selected.v == i and t_anim or 1.0 - t_anim
else
LastActive[v] = false
end
end
local col_bg = imgui.GetColorU32(selected.v == i and imgui.GetStyle().Colors[imgui.Col.ButtonActive] or imgui.ImVec4(0,0,0,0))
local col_box = imgui.GetColorU32(selected.v == i and imgui.GetStyle().Colors[imgui.Col.Button] or imgui.ImVec4(0,0,0,0))
local col_hovered = imgui.GetStyle().Colors[imgui.Col.ButtonHovered]
local col_hovered = imgui.GetColorU32(imgui.ImVec4(col_hovered.x, col_hovered.y, col_hovered.z, (imgui.IsItemHovered() and 0.2 or 0)))
draw_list:AddRectFilled(imgui.ImVec2(p.x-size.x/6, p.y), imgui.ImVec2(p.x + (radius * 0.65) + t * size.x, p.y + size.y), col_bg, 10.0)
draw_list:AddRectFilled(imgui.ImVec2(p.x-size.x/6, p.y), imgui.ImVec2(p.x + (radius * 0.65) + size.x, p.y + size.y), col_hovered, 10.0)
draw_list:AddRectFilled(imgui.ImVec2(p.x, p.y), imgui.ImVec2(p.x+5, p.y + size.y), col_box)
imgui.SetCursorPos(imgui.ImVec2(c.x+(centering and (size.x-imgui.CalcTextSize(v).x)/2 or 15), c.y+(size.y-imgui.CalcTextSize(v).y)/2))
imgui.Text(v)
imgui.SetCursorPos(imgui.ImVec2(c.x, c.y+size.y))
end
return bool
end
function BH_theme()
imgui.SwitchContext()
local style = imgui.GetStyle()
local colors = style.Colors
local clr = imgui.Col
local ImVec4 = imgui.ImVec4
local ImVec2 = imgui.ImVec2
style.WindowPadding = ImVec2(6, 4)
style.WindowRounding = 5.0
style.ChildWindowRounding = 5.0
style.FramePadding = ImVec2(5, 2)
style.FrameRounding = 5.0
style.ItemSpacing = ImVec2(7, 5)
style.ItemInnerSpacing = ImVec2(1, 1)
style.TouchExtraPadding = ImVec2(0, 0)
style.IndentSpacing = 6.0
style.ScrollbarSize = 12.0
style.ScrollbarRounding = 5.0
style.GrabMinSize = 20.0
style.GrabRounding = 2.0
style.WindowTitleAlign = ImVec2(0.5, 0.5)
colors[clr.Text] = ImVec4(1, 1, 1, 1)
colors[clr.WindowBg] = ImVec4(0.09, 0.09, 0.09, 1)
colors[clr.ChildWindowBg] = ImVec4(0.12, 0.12, 0.13, 1)
colors[clr.Button] = ImVec4(1.00, 1.00, 1.00, 1)
colors[clr.TextDisabled] = ImVec4(0.8, 0.8, 0.8, 1.00)
colors[clr.PopupBg] = ImVec4(0.05, 0.05, 0.10, 0.90)
colors[clr.Border] = ImVec4(1, 1, 1, 1.00)
colors[clr.BorderShadow] = ImVec4(0.00, 0.00, 0.00, 0.00)
colors[clr.FrameBg] = ImVec4(0.19, 0.22, 0.26, 1)
colors[clr.FrameBgHovered] = ImVec4(0.22, 0.25, 0.30, 1.00)
colors[clr.FrameBgActive] = ImVec4(0.22, 0.25, 0.29, 1.00)
colors[clr.TitleBg] = ImVec4(0.19, 0.22, 0.26, 1.00)
colors[clr.TitleBgActive] = ImVec4(0.19, 0.22, 0.26, 1.00)
colors[clr.TitleBgCollapsed] = ImVec4(0.19, 0.22, 0.26, 0.59)
colors[clr.MenuBarBg] = ImVec4(0.19, 0.22, 0.26, 1.00)
colors[clr.ScrollbarBg] = ImVec4(0.20, 0.25, 0.30, 0.60)
colors[clr.ScrollbarGrab] = ImVec4(0.41, 0.55, 0.78, 1.00)
colors[clr.ScrollbarGrabHovered] = ImVec4(0.49, 0.63, 0.86, 1.00)
colors[clr.ScrollbarGrabActive] = ImVec4(0.49, 0.63, 0.86, 1.00)
colors[clr.ComboBg] = ImVec4(0.20, 0.20, 0.20, 0.99)
colors[clr.CheckMark] = ImVec4(0.41, 0.55, 0.78, 1.00)
colors[clr.SliderGrab] = ImVec4(1.00, 1.00, 1.00, 0.30)
colors[clr.SliderGrabActive] = ImVec4(0.80, 0.50, 0.50, 1.00)
colors[clr.ButtonHovered] = ImVec4(0.49, 0.62, 0.85, 1.00)
colors[clr.ButtonActive] = ImVec4(0.49, 0.62, 0.85, 1.00)
colors[clr.Header] = ImVec4(0.19, 0.22, 0.26, 1.00)
colors[clr.HeaderHovered] = ImVec4(0.22, 0.24, 0.28, 1.00)
colors[clr.HeaderActive] = ImVec4(0.22, 0.24, 0.28, 1.00)
colors[clr.Separator] = ImVec4(1, 1, 1, 1.00)
colors[clr.SeparatorHovered] = ImVec4(1, 1, 1, 1.00)
colors[clr.SeparatorActive] = ImVec4(1, 1, 1, 1.00)
colors[clr.ResizeGrip] = ImVec4(0.41, 0.55, 0.78, 1.00)
colors[clr.ResizeGripHovered] = ImVec4(0.49, 0.61, 0.83, 1.00)
colors[clr.ResizeGripActive] = ImVec4(0.49, 0.62, 0.83, 1.00)
colors[clr.CloseButton] = ImVec4(0.41, 0.55, 0.78, 1.00)
colors[clr.CloseButtonHovered] = ImVec4(0.50, 0.63, 0.84, 1.00)
colors[clr.CloseButtonActive] = ImVec4(0.41, 0.55, 0.78, 1.00)
colors[clr.PlotLines] = ImVec4(1.00, 1.00, 1.00, 1.00)
colors[clr.PlotLinesHovered] = ImVec4(0.90, 0.70, 0.00, 1.00)
colors[clr.PlotHistogram] = ImVec4(0.90, 0.70, 0.00, 1.00)
colors[clr.PlotHistogramHovered] = ImVec4(1.00, 0.60, 0.00, 1.00)
colors[clr.TextSelectedBg] = ImVec4(0.41, 0.55, 0.78, 1.00)
colors[clr.ModalWindowDarkening] = ImVec4(0.16, 0.18, 0.22, 0.76)
end
BH_theme()
--==[UPDATE]==--
--
-- _ _ _ _____ ___ _ _ ____ ____ _ _____ _____ ______ __ ___ ____ _ _ __
-- / \ | | | |_ _/ _ \| | | | _ \| _ \ / \|_ _| ____| | __ ) \ / / / _ \| _ \| | | |/ /
-- / _ \| | | | | || | | | | | | |_) | | | |/ _ \ | | | _| | _ \\ V / | | | | |_) | | | ' /
-- / ___ \ |_| | | || |_| | |_| | __/| |_| / ___ \| | | |___ | |_) || | | |_| | _ <| |___| . \
-- /_/ \_\___/ |_| \___/ \___/|_| |____/_/ \_\_| |_____| |____/ |_| \__\_\_| \_\_____|_|\_\
--
-- Author: http://qrlk.me/samp
--
function autoupdate(json_url, prefix, url)
local dlstatus = require('moonloader').download_status
local json = getWorkingDirectory() .. '\\'..thisScript().name..'-version.json'
if doesFileExist(json) then os.remove(json) end
downloadUrlToFile(json_url, json,
function(id, status, p1, p2)
if status == dlstatus.STATUSEX_ENDDOWNLOAD then
if doesFileExist(json) then
local f = io.open(json, 'r')
if f then
local info = decodeJson(f:read('*a'))
updatelink = info.updateurl
updateversion = info.latest
f:close()
os.remove(json)
if updateversion ~= thisScript().version then
lua_thread.create(function(prefix)
local dlstatus = require('moonloader').download_status
local color = -1
sampAddChatMessage((prefix..'Обнаружено обновление. Пытаюсь обновиться c '..thisScript().version..' на '..updateversion), color)
wait(250)
downloadUrlToFile(updatelink, thisScript().path,
function(id3, status1, p13, p23)
if status1 == dlstatus.STATUS_DOWNLOADINGDATA then
print(string.format('Загружено %d из %d.', p13, p23))
elseif status1 == dlstatus.STATUS_ENDDOWNLOADDATA then
print('Загрузка обновления завершена.')
sampAddChatMessage((prefix..'Обновление завершено!'), color)
goupdatestatus = true
lua_thread.create(function() wait(500) thisScript():reload() end)
end
if status1 == dlstatus.STATUSEX_ENDDOWNLOAD then
if goupdatestatus == nil then
sampAddChatMessage((prefix..'Обновление прошло неудачно. Запускаю устаревшую версию..'), color)
update = false
end
end
end)
end, prefix)
else
update = false
print('v'..thisScript().version..': Обновление не требуется.')
end
end
else
print('v'..thisScript().version..': Не могу проверить обновление. Смиритесь или проверьте самостоятельно на '..url)
update = false
end
end
end)
while update ~= false do wait(100) end
end
function getNewVersion()
local dlstatus = require('moonloader').download_status
local json = getWorkingDirectory() .. '\\'..thisScript().name..'-version.json'
if doesFileExist(json) then os.remove(json) end
downloadUrlToFile(json_url, json, function(id, status, p1, p2)
if status == dlstatus.STATUSEX_ENDDOWNLOAD then
if doesFileExist(json) then
local f = io.open(json, 'r')
if f then
local info = decodeJson(f:read('*a'))
updatelink = info.updateurl
LAST_VERSION = info.latest
debugmsg('LAST_VERSION UPDATED: '..info.latest)
if LAST_VERSION ~= tostring(thisScript().version) then
sampAddChatMessage(tag..'new version available! (current: '..tostring(thisScript().version)..', last: '..LAST_VERSION, -1)
sampAddChatMessage(tag..'use {698cc7}'..settings.cmd.v..'_update{ffffff} to update!', -1)
end
f:close()
os.remove(json)
end
end
end
end)
end
update 0.2:
- добавлена поддержка буквенных ip адресов
Последнее редактирование: