LINUX.ORG.RU

Предсказуемость математики и луа

 ,


1

1
function hashStr (nome)
	hours, minutes = GetGameTime()
	count1=hours* 3,1415926535
	count2=minutes* 3,1415926535
	count3=count1*count2
	count3=string.sub(count3, 1, 3)
	count3=string.format("%03d",count3)
	hNik=string.byte(nome,1)
	hNik2=string.byte(nome,2)
	hNome=hNik*hNik2
	hNome=string.sub(hNome, 1, 3)
	hNome=string.format("%03d",hNome)
	r1=string.sub(count3, 1, 1)
	r2=string.sub(hNome, 1, 1)
	r3=string.sub(count3, 2, 2)
	r4=string.sub(hNome, 2, 2)
	r5=string.sub(count3, 3, 3)
	r6=string.sub(hNome, 3, 3)
	r=r1 .. r2 .. r3 .. r4 .. r5 .. r6
	return r
end

hours, minutes = GetGameTime() получает текущие час и минуту в формате: 01 22

Скармливаем слово на одном компе - получаем предсказуемо одинаковый результат. Скармливаем на другом компе получаем тоже предсказуемо одинаковый результат, но не такой, как на предыдущем компе. Это как вообще? Данные одинаковые. Ник один и тот же. Время одно и то же. Результат всегда разный. Это вообще законно?! Время возвращается серверное - одинаковое и там и там.

Перемещено Dimez из general

★★★★★

Последнее исправление: hobbit (всего исправлений: 2)

Ответ на: комментарий от Virtuos86

А вот нихрена…. Новый заново переписанный блок:

local nachalo = string.sub(message, 1, 1)
    print (str)
    print (message)
	if message == "ВОЖДЬ, простой!" and nachalo~="*" then
		if TDG[sender]==nil then
			TDG[sender]={}
		end
		if TDG[sender][endQuests]==nil then
			TDG[sender][endQuests]={}
		end
		local guokTimerStart=pQuests[1][1]
		if TDG[sender][endQuests][guokTimerStart]~=nil then
            if TDG[sender][qAchiv]==nil of TDG[sender][qAchiv]=="9999" then
				countQ=tablelength(pQuests[1])
				local chisloProstyhQComplit=0
				chisloProstyhQComplit=tonumber(chisloProstyhQComplit)
				for testQ=1, countQ do
					local x = math.random(1, countQ)
					ach=pQuests[1][x]
					if TDG[sender][endQuests][x]~="1" then
						SendChatMessage(hsh .. " 001 " .. sender .. ", покажи мне ачивку " .. ach .. " " .. GetAchievementLink(ach), "guild", nil, 1)
						break
					else
						chisloProstyhQComplit=chisloProstyhQComplit + 1
						if chisloProstyhQComplit==countQ then
							SendChatMessage("*" .. sender .. ", все простые квесты уже выполнены. Добавить переход на следущий уровень квестов.", "guild", nil, 1)
						end
					end
				end
            else
                ach=TDG[sender][qAchiv]
                SendChatMessage(hsh .. " 004 " .. sender .. ", у тебя уже взят квест: " .. ach .. GetAchievementLink(ach), "guild", nil, 1)
            end
		else
			ach=pQuests[1][1]
			SendChatMessage(hsh .. " 001 " .. sender .. ", покажи мне ачивку " .. ach .. " " .. GetAchievementLink(ach), "guild", nil, 1)
		end
	end

	if string.find (message, hsh) and string.find (message, "002") then
		msg1=mysplit(message)
		msg1=msg[6]
		TDG[sender][endQuests][msg1]="1"
	end

Не работает с первого же притна. И сиди сумрачно наблюай, думай - а что же не так то? Явно где то не так переменная использоана или таблица. Или опечатка.

Самое надежное, что я нашел - нахер удалять все (ибо даже комментироание не помогает - эта падла считает ошибки в комментированном коде - ошибками). Удаляешь все и заново переписывешь с комментированием каждйо строки.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Что то у тебя громоздкий код, вынеси повторяющийся код в функции чтоб код проще смотрелся. Я конечно не lua программист, но вот эта строка меня смущает:

            if TDG[sender][qAchiv]==nil of TDG[sender][qAchiv]=="9999" then

Вот это «of» посредине не имеется ли ввиду «or»? Lua что такое ест без ошибок или предупреждений?

V1KT0P ★★
()
Ответ на: комментарий от LightDiver

Например вот такую строку:

SendChatMessage(hsh .. " 001 " .. sender .. ", покажи мне ачивку " .. ach .. " " .. GetAchievementLink(ach), "guild", nil, 1)

Переписать как-то вот так:

SendChatMessage(string.format("%s %03d %s, %s %s %s", hsh, 1, sender, "покажи мне ачивку", ach, GetAchievementLink(ach)), "guild", nil, 1)

А если string.format спрятать внутри функции fmt и статические строки внутрь внести то еще проще будет:

SendChatMessage(fmt("%s %03d %s, покажи мне ачивку %s %s", hsh, 1, sender, ach, GetAchievementLink(ach)), "guild", nil, 1)
V1KT0P ★★
()
Ответ на: комментарий от V1KT0P

Ну вот и первая опечатка. Спасибо, долго бы я искал.

Вообще это проверка что в таблице отсутствует текущий квест или он «9999», то есть считается выполненным, а нового нету.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от V1KT0P

А почему так? Я эти все символы распарсить не могу. А свою обосновать могу. Я решил команды системные кодами описывать. 001, 002 итд. Если вместе с командой есть хэш-код, значит строка точно нужная. В итоге всего два совпадения искать. А вот регекспы я пока не понимать…

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от V1KT0P

https://pastebin.com/s5fDAFz0

Жесть какая то.. ну жесть. Вырезал вообще все, кроме нового блока. Не работает. С первой же строки. А значит - критическая ошибка где то в коде. Вот как с тем of. И никакими принтами не отловишь… ой.. Чую это надолго. Кажись проще переписать с нуля. Полностью с нуля.

Самое поганое, что остальные блоки без этого тоже не работают. Чот я нарушил кардинально последними правками. Аххаха… Ну жесть.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Советую тебе выносить как можно больше кода в независимые функции и писать юнит тесты для них. Особенно учесть граничные случаи. Так будет меньше головной боли, опечатки и ошибки проще отлавливать.

V1KT0P ★★
()
Ответ на: комментарий от V1KT0P

Самое поганое, что остальные блоки без этого тоже не работают. Чот я нарушил кардинально последними правками. Аххаха… Ну жесть.

Или взять из гита последнюю рабочую версию и ее пилить. Но там несколько дней кода, блин…

Да, я про функции знаю, выношу, если нужно пользоваться несколько раз.

https://github.com/Vladgobelen/GuildChat/blob/main/expp.lua

Вот тут я вообще 95% логики в одну функцию вынес.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от V1KT0P

Хер знает, заработало внезапно. Походу of тот все ломал реально, а остальное более менее приличное. А я не сразу перезагрузил правильно. Тут чтобы применить изменения, нужно интерфейс весь перезагружать. Иногда даже клиент полностью перезапускать. Очень нестабильная работа. Спасибо огромное. 10 часов поисков, блин.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от V1KT0P

Что такое юнит тесты?

Тут еще косяк лютый в том, что сохранить данные можно тоже только перезагрузив клиент. Только при выходе из игры глобальные переменные записываются в файл. Закрыл неправильно? Все пропало.

А данные эти только у тебя.. Нужно тестить работу с другими игроками - это уже совсем другое дело. Тут тебе и проверки таблиц в других местах и вообще. А еще этих игроков найти для теста нужно, да терпеливых. Работа не быстрая, короче.

В итоге, сначала максимально правдоподобно описываешь целый блок, а то и два.. Ну, чтобы логично и последовательно. Потом думаешь почему это не работает у тебя. Чинишь у себя. Потом думаешь почему это не работает у других.. Потом понимаешь, что за все эти попытки наворотил столько костылей, что проще переписать и начинаешь с нуля.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 2)
Ответ на: комментарий от V1KT0P

Я вчитался и понял что тут происходит. Очень интересно, но косяк в том, что теперь добавляется скобок, которые можно упустить, запятых, порядок слов не сразу очевидный. Оно красивее, но более подвержено опечаткам.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LightDiver

https://ru.wikipedia.org/wiki/Модульное_тестирование

Суть тестов том что ты тестируешь небольшие куски независимого кода тем самым давая гарантию что код не содержит ошибок. Наглядный пример, у тебя есть файл main.lua:

function mysplit(inputstr, sep)
    if sep == nil then
        sep = "%s"
        end
        local t={}
        for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
            table.insert(t, str)
        end
        return t
end

someFunction(mysplit(getData(), ","))

И ты не знаешь правильно работает ли функция «mysplit» или нет. Для этого ты выносишь её в отдельный файл «myLibrary.lua»:

function mysplit(inputstr, sep)
    if sep == nil then
        sep = "%s"
        end
        local t={}
        for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
            table.insert(t, str)
        end
        return t
end

А в «main.lua» импортируешь функцию из файла «myLibrary.lua»:

require "myLibrary"

someFunction(mysplit(getData(), ","))

Теперь у тебя появляется возможность вызывать функцию «mysplit» независимо и для тестов к примеру создаешь файл «myLibrary_test.lua» в котором тестируешь функцию на граничные случаи которые могут случиться:

require "myLibrary"

function test(text, delimiter, expectedText)
    result = mysplit(text, delimiter)
    result = table.concat(result, "_")
    if result ~= expectedText then
        print(string.format("[Error] Text: '%s', result: '%s', expected: '%s'", text, result, expectedText))
    end
end

-- Проверяем граничный случай пустая строка.
test("", ".", "")

test("Test", ".", "Test")
test("Test.word", ".", "Test_word")
test("Test,word", ",", "Test_word")

-- Проверяем длинные разделители.
test("Test,_word", ",_", "Test_word")

-- Проверяем что при разделении пустые строки отбрасываются.
test("..Test...word.", ".", "Test_word")

Теперь для проверки что функция работает как надо тебе просто надо запустить на выполнение «myLibrary_test.lua» и убедиться что нет ошибок. Теперь если ты захочешь ускорить функцию переписав её без «gmatch» ты можешь не бояться сломать ибо тесты это покажут. Почитай статьи про это, обычно для популярных языков есть фреймворки которые упрощяют это и обычно это выглядит так: запускаешь тесты скриптом и в конце получаешь результат «Успех» если все нормально или показывается количество и название проваленых тестов с диагностикой.

Так как тебе приходится тестировать игровые ситуации то тебе надо разграничить свой код и взаимодействие с сервером через абстракцию которая позволит тебе тестировать без игроков и запуска сервера. У тебя должен быть отельный файл типа «server_simulation.lua» который позволит тебе симулировать работу с сервером через абстракцию. Так ты сможешь делать продвинутые юнит тесты, которые уже будут смахивать на end to end тестирование. А добавив GUI для управления этой симуляцией сможешь сам типа «играть» за игроков.

V1KT0P ★★
()
Ответ на: комментарий от V1KT0P

Ой, это вообще боль. Я узнал про require и хотел вообще все функции вынести в отдельный файл и вызывать. Оказалось, в wow api такая возможность отсутствует. Я могу, конечно эмулировать апи и вставлять статичные куски кода, но… Это добавляет возможностей опечаток - раз, и что то я могу упустить и не проэмулировать. Надежнее тестировать в игре.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Я узнал про reqiery и хотел вообще все функции вынести в отдельный файл и вызывать. Оказалось, в wow api такая возможность отсутствует.

Хреново, тогда можно вручную каждый раз копировать свои функции в отдельный файл для тестов. Так еслиб у тебя тот блок кода с «of» был независимым и ты бы его скопировал в отдельный файл для тестов то при запуске юнит теста ты бы сразу получил ошибку. Это гораздо быстрее чем запустить сервер, подождать игроков и протестировать функционал вручную. Тут конечно важен опыт чтоб правильно организовать архитектуру кода, но лучше сразу начать пытаться потом легче будет.

V1KT0P ★★
()
Ответ на: комментарий от V1KT0P

Сервер чужой. Это Сирус - достаточно популярный проект. Его то запускать не надо. А вот клиент надо, да.. Вообще просто очень мало знаний по теме. Можешь считать что я в программировании две недели по сути. Я скорее всего сам использую костыли там, где можно этого не делать, потому что не знаю пока как правильно.

Усугубляется еще тем, что даже урезанный wow api у них еще больше урезан. Запрещены программно некоторые функции. А за что то и банят. И нужно вот искать наугад все это.

https://forum.sirus.su/threads/wow-api-na-sirus.301164/#post-2565941

Вот не работает у них одна функция. Должна выдавать одно, а выдает другое. Написал и получил в ответ: «А с чего ты решил, что оно не должно так работать? Гуляй лесом.»

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Я когда писал плагины для сервера CS:GO делал это без юнит тестов ибо там кода было немного, но приходилось очень внимательно продумывать граничные случаи и то иногда упускал очень редкие ситуации. А так надо внимательно читать, я так бегло глянул что это за wow api и например нашел такое:

"CHAT_MSG_GUILD"
	Category: Communication,Guild
  	

Fired when a message is sent or received in the Guild channel.

arg1
    Message that was sent
arg2
    Author
arg3
    Language that the message was sent in
arg11
    Chat lineID
arg12
    Sender GUID

Тоесть если не ошибаюсь если сделать вот так:

GC_Sniffer:SetScript("OnEvent", function (self, event, message, sender, _, _, _, _, _, _, _, _, chatLineID, senderGUID)

То в «chatLineID» будет идентификатор чата а в «senderGUID» будет уникальный 64 битный номер типа «0x00000000012729FD».

При чем он там хранит определенные данные:

0xAABCCCDDDDEEEEEE
AA: неизвестно.
B: 0 - игрок, 1 - объект мира, 3 - NPC и временные питомцы, 4 - постоянный питомец, 5 - транспорт.
EEEEEE - если игрок то это уникальный номер игрока. Вроде как возможно даже что DEEEEEE.

То есть по идеи младшие 3 байта(шесть шестнадцатеричных чисел) GUID это уникальный идентификатор игрока и не надо мудрить с хешем.

V1KT0P ★★
()
Ответ на: комментарий от V1KT0P

Машу вашу.. я забыл. Я тупо забыл, что у каждого игрока в игре есть уникальный код. Я нашел это в самом начале еще недели две назад. Ох блин… Спасибо.

Но с хэшем мудрить надо. Мне нужно чтобы подделать строку не могли. То есть не могли вручную сгенерировать запрос. Только автоматический ответ аддона.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Вот не работает у них одна функция. Должна выдавать одно, а выдает другое. Написал и получил в ответ: «А с чего ты решил, что оно не должно так работать? Гуляй лесом.»

Пробовал как советует документация вызывать «GuildRoster» и ждать пока прилетит событие «GUILD_ROSTER_UPDATE»?

Еще там можно попробовать подергать «SetGuildRosterShowOffline(false)» и «SetGuildRosterShowOffline(true)» может поможет.

Еще можно втупую попробовать вызывать «GetGuildRosterInfo» пока будут возвращаться корректные данные.

Ну или еще какой костыль поискать.

V1KT0P ★★
()
Ответ на: комментарий от V1KT0P
local kol=0
                for guokZ=1,GetNumGuildMembers(true) do
                    local name, rankName, rankIndex, level, classDisplayName, zone, publicNote, officerNote, isOnline, status, class, achievementPoints, achievementRank, isMobile, canSoR, repStanding, guid = GetGuildRosterInfo(guokZ)
                        kol=kol+1
                end
                local kol1=kol+30
                SendChatMessage("*" .. sender .. ", сейчас в гильдии " .. kol .. " игроков. Должно стать " .. kol1, "OFFICER", nil, 1);
                TDG[sender]["доп_квест"]=kol1

Я перебором считаю. Тупо перебираю всех учасников гильдии и по счетчику.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от dataman

В старших версиях lua ютф8 есть из коробки для базовых манипуляций. Только вот ТС работает с урезанной песочницей из игры и у него нет возможности что-то подключать.

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)

По делу скажу только, что версии Lua начиная с 5.3 можно собрать с 32-битными и 64-битными числами, а что там встроено в какую-то игру — чёрт знает (может, патченная древняя версия со своими приколами). Проще, как уже написали навтыкать принтов, и посмотреть, где начинаются разные результаты.

Про запятые вместо точек в числах тут уже поругались, скажу ещё про глобальные переменные. Переменные нужно объявлять через local, если не хочешь их видеть из любого места программы (и когда-нибудь поиметь проблем): local hours, minutes = GetGameTime().

Если поставишь luacheck или lua-language-server, таких типовых ошибок допускать не будешь.

Ceiling_QB ★★★★
()
Последнее исправление: Ceiling_QB (всего исправлений: 3)
Ответ на: комментарий от dataman

И что тебе выводит string.upper(«привет») в старших версиях?

Тоже самое что и ввёл выведет конечно =)

для базовых манипуляций

Вся суть который в одном получить символ и всё :D Ну ладно ещё получить их количество. Дальше всё сам. Для более менее удобной работы да надо подключать внешнее, но он не может. Опять же надо уточнять как собрано и что доступно на уровне серверов, может там подключена какая библиотека уже.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от dataman

Луа на то и создана что её как угодно можешь собирать под себя в том и суть. Только вот как она собрана и с чем и какие есть у неё модули надо уточнять в документации на игру, там может быть что угодно, это да. Я не знаю, WoW не тыкал, у ТС даже require замаскирована/стёрта. Хотя никто не запретит просто понавыдирать нужные куски и вставить себе, вся целиком lua-utf8 нужна почти никогда, только вот беда дам часть кода на Си, так что опять облом, но это можно переписать на чистой lua. Короче одно дело когда у тебя своя lua и совсем другое когда у тебя песочница от игры.

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от dataman

почти никогда

Lite https://github.com/rxi/lite я уже давно использовал, даже пару месяцев только им и пользовался, так, по приколу. А вот форка не видел. Ну там понятно, текстовый редактор, но насколько я помню в Lite была своя реализация utf8. XL не трогал.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Проблема уменьшилась, походу, но осталась. Смотри какая фигня:

https://pastebin.com/zmntcXTT

Три запроса. Код совпал только с третьего раза. Первые два отличаются:

Веренс 533023 < первая попытка. Код должен быть 530033

Веренс 533023 < вторая попытка. Код должен быть 530033

И, наконец, третья попытка:

Веренс 533023. И дальше он в запросах.

Ну.. и дальше раз за разом код не совпадает:

[26:06][G] [Веренс]: ВОЖДЬ, сдать
[26:06]Веренс736093
[26:06]Хэвлок736493
[26:06][Офицер] [Хэвлок]: 734003 #aaf >Веренс<, а сделал ли ты 964 [Полетели?]?
[26:10][G] [Веренс]: ВОЖДЬ, сдать
[26:10]Веренс736093
[26:10]Хэвлок736493
[26:10][Офицер] [Хэвлок]: 734003 #aaf >Веренс<, а сделал ли ты 964 [Полетели?]?
[26:14][G] [Веренс]: ВОЖДЬ, сдать
[26:14]Веренс736093
[26:14]Хэвлок736493
[26:14][Офицер] [Хэвлок]: 734003 #aaf >Веренс<, а сделал ли ты 964 [Полетели?]?
[26:16][G] [Веренс]: ВОЖДЬ, сдать
[26:16]Веренс736093
[26:16]Хэвлок736493
[26:16][Офицер] [Хэвлок]: 734003 #aaf >Веренс<, а сделал ли ты 964 [Полетели?]?
[26:17][G] [Веренс]: ВОЖДЬ, сдать
[26:17]Веренс736093
[26:17]Хэвлок736493
[26:17][Офицер] [Хэвлок]: 734003 #aaf >Веренс<, а сделал ли ты 964 [Полетели?]?

И вот, на 20-30 запрос:

[27:33][G] [Веренс]: ВОЖДЬ, сдать
[27:33]Веренс739093
[27:33]Хэвлок739493
[27:33][Офицер] [Хэвлок]: 739093 #aaf >Веренс<, а сделал ли ты 964 [Полетели?]?
[27:33]Веренс739093
[27:33]Веренс739093
[27:33][Офицер] [Веренс]: *я забыл...скоро сделаю, вернусь позже.

Только через минуту сработало. И дальше снова работате. Короче, хаос какой то.

[41:18][G] [Веренс]: ВОЖДЬ, сдать
[41:18]Веренс132013
[41:18]Веренс132013
[41:18][Офицер] [Веренс]: Веренс 3 41
[41:18]Веренс132013
[41:18]Хэвлок132413
[41:18][Офицер] [Хэвлок]: Хэвлок 3 40
[41:18]Веренс132013
[41:18]Хэвлок132413
[41:18][Офицер] [Хэвлок]: 131083 #aaf >Веренс<, а сделал ли ты 964 [Полетели?]?
[41:23]fdsfa
[41:23][G] [Веренс]: ВОЖДЬ, сдать
[41:23]Веренс132013
[41:23]Хэвлок132413
[41:23][Офицер] [Хэвлок]: Хэвлок 3 40
[41:23]Веренс132013
[41:23]Веренс132013
[41:23][Офицер] [Веренс]: Веренс 3 41
[41:23]Веренс132013
[41:23]Хэвлок132413
[41:23][Офицер] [Хэвлок]: 131083 #aaf >Веренс<, а сделал ли ты 964 [Полетели?]?
[41:25]fdsfa
[41:25][G] [Веренс]: ВОЖДЬ, сдать
[41:25]Веренс132013
[41:25]Веренс132013
[41:25][Офицер] [Веренс]: Веренс 3 41
[41:25]Веренс132013
[41:25]Хэвлок132413
[41:25][Офицер] [Хэвлок]: Хэвлок 3 40
[41:25]Веренс132013
[41:25]Хэвлок132413
[41:25][Офицер] [Хэвлок]: 131083 #aaf >Веренс<, а сделал ли ты 964 [Полетели?]?
[41:29]fdsfa
[41:29][G] [Веренс]: ВОЖДЬ, сдать
[41:29]Веренс132013
[41:29]Веренс132013
[41:29][Офицер] [Веренс]: Веренс 3 41
[41:30]Веренс132013
[41:30]Хэвлок132413
[41:30][Офицер] [Хэвлок]: Хэвлок 3 40
[41:30]Веренс132013
[41:30]Хэвлок132413
[41:30][Офицер] [Хэвлок]: 131083 #aaf >Веренс<, а сделал ли ты 964 [Полетели?]?
[41:32]fdsfa
[41:32][G] [Веренс]: ВОЖДЬ, сдать
[41:32]Веренс132013
[41:32]Веренс132013
[41:32][Офицер] [Веренс]: Веренс 3 41
[41:32]Веренс132013
[41:32]Хэвлок132413
[41:32][Офицер] [Хэвлок]: Хэвлок 3 41
[41:32]Веренс132013
[41:32]Хэвлок132413
[41:32][Офицер] [Хэвлок]: 132013 #aaf >Веренс<, а сделал ли ты 964 [Полетели?]?
[41:32]Веренс132013
[41:32]Веренс132013
[41:32][Офицер] [Веренс]: *я забыл...скоро сделаю, вернусь позже.
[41:53]fdsfa
[41:53][G] [Веренс]: ВОЖДЬ, сдать
[41:53]Веренс132043
[41:53]Веренс132043
[41:53][Офицер] [Веренс]: Веренс 3 42
[41:54]Веренс132043
[41:54]Хэвлок132443
[41:54][Офицер] [Хэвлок]: Хэвлок 3 41
[41:54]Веренс132043
[41:54]Хэвлок132443
[41:54][Офицер] [Хэвлок]: 132013 #aaf >Веренс<, а сделал ли ты 964 [Полетели?]?
[41:58]fdsfa
[41:58][G] [Веренс]: ВОЖДЬ, сдать
[41:58]Веренс132043
[41:58]Веренс132043
[41:58][Офицер] [Веренс]: Веренс 3 42
[41:58]Веренс132043
[41:58]Хэвлок132443
[41:58][Офицер] [Хэвлок]: Хэвлок 3 41
[41:58]Веренс132043
[41:58]Хэвлок132443
[41:58][Офицер] [Хэвлок]: 132013 #aaf >Веренс<, а сделал ли ты 964 [Полетели?]?
[42:00]fdsfa
[42:00][G] [Веренс]: ВОЖДЬ, сдать
[42:00]Веренс132043
[42:00]Веренс132043
[42:00][Офицер] [Веренс]: Веренс 3 42
[42:00]Веренс132043
[42:00]Хэвлок132443
[42:00][Офицер] [Хэвлок]: Хэвлок 3 41
[42:00]Веренс132043
[42:00]Хэвлок132443
[42:00][Офицер] [Хэвлок]: 132013 #aaf >Веренс<, а сделал ли ты 964 [Полетели?

Ну я даже не знаю что сказать. Время отличается. Выслушаю идеи.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 5)
Ответ на: комментарий от LINUX-ORG-RU

По итогу: Я не мог поймать баг, потому что сервер иногда отдает время правильно, а иногда рандомно. Я хз как так. Ну и что еще можно использовать?

Вроде как юниксовое время совпадает. Нужно проверить. Вот только как его использовать..

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

Пришла беда откуда не ждали. С никами тоже не все благополучно. Возвращаюсь к вопросу математики - может я туплю. Почему string.byte на разные буквы возвращает одинаковые коды?

i=string.byte(«Двацветок»,1); print (i)

208

i=string.byte(«Железобетонс»,1); print (i)

208

Короче, первая всегда 208. Вторая колеблется от 140 до 155.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)

Понавтыкай отладочный print через каздую строчку в тотором выводи все переменные и их типы и поймешь где возникает расхождение на разных машинах, а уже потом придумаем как это побеждать

pihter ★★★★★
()
Ответ на: комментарий от pihter

Ответ дает сервер. Это серверное время, а не машинное. А он может отдать 50 минуту, когда уже середина 51. Я сейчас пробую использовать юниксовое время, оно вроде более стабильное. Но у меня возник технический вопрос:

function alfabet (bookv)
shablon="абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	myB=string.find(shablon,bookv)
	return myB
end

Почему на кириллицу всегда только нечетные цифры? 1, 3, 5 итд.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от Forum0888

Мне как то все это казалось раньше более стабильным что ли. Более того - с отсутствием фантазии и хоть какого то рандома. Пишешь «а» - получаешь «а» и никак иначе. Это же компьютер.

А тут, то что получаешь, зависит от железа, от оси, от расположения, от времени, от софта, от версий, от желания левого заднего копыта соседа. Ну это ненормально. Как вообще с этим работают в крупных проектах тогда?

https://github.com/Vladgobelen/SirusOFF

Вот есть у меня такой скриптик в нескольких вариантах. Чисто ради спортивного интереса одна из версий на си. Угадайте какая из версий не работает?

https://github.com/Vladgobelen/SirusOFF/blob/main/off.c

Правильно - си. Причем двое-трое суток работало. Идеально работало, жрало памяти в несколько раз меньше. А потом в переменных начал появляться мусор рандомный. Ты ему назначаешь в переменную «2», а обратно читается #*#2 или что то подобное.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Пришла беда откуда не ждали. С никами тоже не все благополучно. Возвращаюсь к вопросу математики - может я туплю. Почему string.byte на разные буквы возвращает одинаковые коды?

Потому что utf8: https://ru.wikipedia.org/wiki/UTF-8

Сейчас стандарт Unicode по символам для разных языков содержит около 150 000 символов. А байт умещает только 256 значений, два байта только 65 536. Поэтому используются кодировка байтов с переменным числом байтов.

И то что возвращается 208 а это D0 совершенно логично ибо:

П - D0 9F
Д - D0 94

С текстом с переменной кодировкой работай как с массивом байтов а не как с символами. Обычно в нормальных языках можно узнать длину в символах или в байтах. Тебе лучше работать как с массивом байтов, проще будет.

А тут, то что получаешь, зависит от железа, от оси, от расположения, от времени, от софта, от версий, от желания левого заднего копыта соседа. Ну это ненормально. Как вообще с этим работают в крупных проектах тогда?

Добро пожаловать в разработку программного обеспечения =). Тут может сломаться программа для парсинга на другом компе просто по тому что там в системных настройках разделитель целой и дробной части в числах изменен с точки на запятую или обратно.

У тебя самых худший вариант. Мало того что lua это скриптовый слаботипизированный динамический язык, так он у тебя еще и урезан и ты не можешь для нормального программирования подключить библиотеки. Так еще и разрабатываешь для игры где еще куча костылей может понадобиться. Вот из-за таких ситуаций и повляются Electron и иже с ним когда простенькая программа для показа текста тянет целый chrome только для того чтоб абстрагироваться от операционной системы и гарантировать что на другом компе код не сломается.

V1KT0P ★★
()
Ответ на: комментарий от LightDiver

Такая ныне селяви у программистов.

Ныне век в котором 2000 ЯП это норма.

Почему так?

Потому что не создаются новые технологии разработки.

Что касаемо SQL, то его популярность связана с тем, что для многих задач использование таблиц и индексов вполне достаточно для их реализации.

Шутка

«Настоящих буйных мало, вот и имеем SQL».

Forum0888
()
Ответ на: комментарий от LightDiver

Правильно - си. Причем двое-трое суток работало. Идеально работало, жрало памяти в несколько раз меньше. А потом в переменных начал появляться мусор рандомный. Ты ему назначаешь в переменную «2», а обратно читается #*#2 или что то подобное.

Строка в Си это массив байт заканчивающийся на байт 00. Вот ты создаешь переменную два байта длиной и читаешь в нее:

char line[2];
            TwoNull = popen("netstat |grep '7776 ESTABLISHED' | awk '{print $2}'", "r");
            while ( fread(line, 2, sizeof(line), TwoNull))
            {
                line1 = atoi (line);

Вот тут у тебя две грубейшые ошибки:

  1. Ты хочешь записать в переменную line два значения но без байта «00» в конце это не строка получается а просто массив, а atoi принимает указатель на строку. И тут если в памяти после line лежит ноль то тебе повезло, если нет то функция atoi будет читать память пока не найдет ноль или пока не прекратит парсинг ибо следующий байт не цифра.

  2. Ты не внимательно прочитал что делает функция fread:

 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 
Функция fread считывает элементы данных nmemb (с размером каждого size байтов) с потока, на который указывает stream, и сохраняет их в позиции, на которую указывает ptr. 

Так вот она nmemb раз копирует данные длиной size в ptr. Тоесть будет скопировано nmemb*size элементов. В твоем случае копируется 4 байта в массив длина которого 2 байта. Это назывется overflow, и тут уже ни о какой дальнейшей корректной работе программы говорить не приходится если она начинает портить память.

V1KT0P ★★
()
Ответ на: комментарий от V1KT0P

А как правильно указать? И еще про фрид. Там три варианта: fread, fgetc и fgets. И вот они нихрена у меня не работают. Я тупо перебором подобрал тот, который хоть что то выводил приличное.

LightDiver ★★★★★
() автор топика