Всем привет, подскажите пожалуйста, как реализовать новый свой пакет на стороне клиента, скажем нужно отправлять пакет на сервер при изменении языка интерфейса с 1 байтом индекса выбранного языка.
Посмотрите видео ниже, чтобы узнать, как установить наш сайт в виде веб-приложения на главном экране.
Примечание: Эта функция может быть недоступна в некоторых браузерах.
а какой у вас протокол.Всем привет, подскажите пожалуйста, как реализовать новый свой пакет на стороне клиента, скажем нужно отправлять пакет на сервер при изменении языка интерфейса с 1 байтом индекса выбранного языка.
virtual ~IPacket() {};
virtual bool Encode(network::Stream *stream);
virtual bool Decode(network::Stream *stream);
У меня клиент epilogue, точный протокол не помнюа какой у вас протокол.
Если у вас 286+ - интерфейс с нативками можно сделать, как сейчас делают все ессенс проекты.
Если ниже Prelude of War - использовать байпасы (как вариант) и/или другие доступные пакеты со сторокой. Свой пакет... ну там есть какие-то ручные конструкторы типо от такокого
C:virtual ~IPacket() {}; virtual bool Encode(network::Stream *stream); virtual bool Decode(network::Stream *stream);
ну бог поможетУ меня клиент epilogue, точный протокол не помню
--> использовать байпасы (как вариант)У меня клиент epilogue, точный протокол не помню
так клиент и так шлет пакет в зависимости от того что указано в localization.iniнужно отправлять пакет
Ну єто при входе, а не при смене язьіка. )так клиент и так шлет пакет в зависимости от того что указано в localization.ini
по крайней мере на хфе так
Ну я так вот и реализовал, добавил команду /lang и сделал обработчик на сервере, который при вызове изменяет язык на противоположный, с рус на англ и обратно.--> использовать байпасы (как вариант)
Вот решение в твоем случае
Ну я отследил полученые пакеты при изменении языка, клиент шлет пакет запроса на список умений. Может к нему как-то прикрутить отправку 1 байта? Так возможно?Ну, на епилоге либо старьіе пакетьі костьілять, либо ест писать. )
Ну да есть пакет который при входе отправляет индекс языка, но потестив его, там независимо от моего языка вчегда 2ка приходит, хотя в локал ини меняется, даже если перезапучтить клиент.так клиент и так шлет пакет в зависимости от того что указано в localization.ini
по крайней мере на хфе так
можно просто прикрутить смену языка на сервере в зависимости от того какой id локализации в клиенте
Екстом изменить структуру пакета - без вопросов, изе, но я бьі реквест скил лист не костьілял, клиент много где его шлет, нафига каждьій раз серверу язьік слать. ) Лучше отдельньій реквестн на конкретньій ивент сменьі язьіка (не уверен, как на епилоге, но может бьіть 1900 - EV_LanguageChanged ид ) слать. Что касаемо "костьілять деолтньіе пакетьі", то я имел ввиду те же байпасьі, или, не знаю, реквест заточки/юз итема с минусовьіми значениями слать, етк. Но действительно, зачем такие страдания вокруг довольно банальной фигни, почему не хотите байпас с лозунгом "и так сойдет"? Ведь тут действительно, весьма себе сойдет. )Ну я отследил полученые пакеты при изменении языка, клиент шлет пакет запроса на список умений. Может к нему как-то прикрутить отправку 1 байта? Так возможно?
Ну я так и сделал через байпас, добавил в бд колонку language для таблици персонажа, туда enum, что-бы при каждом входе не выставлять язык нужный заново, потом добавил команду новую /lang которая изменяет язык по типу состояния бежать/идти, все работает хорошо, я почему про пакеты и спрашивал, что-бы не разделять как-бы 1 функцию языка на 2 составляющие, одна получается клиентская, вторая серверная, игроку по сути удобнее в настройках указать язык и играть дальше, чем указывать в 2х местах, и командой и в настройках, конечно по сути это мелочь, один раз настроил и готово. Ну а вообще интересно как, где и через что открыть файлы отвечающие за пакеты, можно посмотреть структуру? Изменить под себя? Вот ui я открываю, в interface.xdat правлю окна а в ui функции, я так понимаю отсюда нельзя пакет слать? Вот этот момент интересен, спасибо.Екстом изменить структуру пакета - без вопросов, изе, но я бьі реквест скил лист не костьілял, клиент много где его шлет, нафига каждьій раз серверу язьік слать. ) Лучше отдельньій реквестн на конкретньій ивент сменьі язьіка (не уверен, как на епилоге, но может бьіть 1900 - EV_LanguageChanged ид ) слать. Что касаемо "костьілять деолтньіе пакетьі", то я имел ввиду те же байпасьі, или, не знаю, реквест заточки/юз итема с минусовьіми значениями слать, етк. Но действительно, зачем такие страдания вокруг довольно банальной фигни, почему не хотите байпас с лозунгом "и так сойдет"? Ведь тут действительно, весьма себе сойдет. )
Так и не надо две, в клиентскую, когда игрок меняет язьік, добавить отправку байпаса на сервер, профит. ) Либо на ивент сменьі язьіка, либо на саму кнопку/подтверждение сохранения настроек, или где там у вас смена язьіка вьіведена.что-бы не разделять как-бы 1 функцию языка на 2 составляющие, одна получается клиентская, вторая серверная, игроку по сути удобнее в настройках указать язык и играть дальше, чем указывать в 2х местах, и командой и в настройках
Для єтих хроник, смотреть нужно в енжин длл, соответственно инструментьі - ида, гидра, етк.Ну а вообще интересно как, где и через что открыть файлы отвечающие за пакеты, можно посмотреть структуру?
Писать хук на пакетку.Изменить под себя?
Ну, только часть уже сформированьіх в нативки пакетьі запросов, а-ля тот самьій реквест юз итем, скил лист, енчант и тд, прямо заслать свой пакет с новьім опкодом и структурой без допилов не вьійдет.Вот ui я открываю, в interface.xdat правлю окна а в ui функции, я так понимаю отсюда нельзя пакет слать?
native final function RequestBypassToServer( string strPass );
function OnLoad()
{
local int i;
local int nMultiSample;
local bool bEnableEngSelection;
local ELanguageType Language;
local string strResolution;
dScript = DialogBox(GetScript("DialogBox"));
bPartyMember = false;
bPartyMaster = false;
// bPartyRoomMaster = false;
// Lootingtype = 0;
if(CREATE_ON_DEMAND==0)
OnRegisterEvent();
if(CREATE_ON_DEMAND==0)
InitHandle();
else
InitHandleCOD();
m_bAirState = false;
// 2006/03/26 - added register state by NeverDie. multi-registering states can only be placed in uc...
RegisterState( "OptionWnd", "GamingState" );
RegisterState( "OptionWnd", "LoginState" );
// Shader version
GetShaderVersion( nPixelShaderVersion, nVertexShaderVersion );
GetResolutionList( ResolutionList );
SetOptionBool( "Game", "HideDropItem", false );
for( i = 0; i < ResolutionList.Length; ++i )
{
strResolution = "" $ ResolutionList[ i ].nWidth $ "*" $ ResolutionList[ i ].nHeight $ " " $ ResolutionList[ i ].nColorBit $ "bit";
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.ResBox", strResolution );
}
ResetRefreshRate();
/*
GetRefreshRateList( RefreshRateList );
class'UIAPI_COMBOBOX'.static.Clear( "OptionWnd.RefreshRateBox" );
for( i = 0; i < RefreshRateList.Length; ++i )
{
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.RefreshRateBox", RefreshRateList[ i ] $ "Hz" );
}
*/
nMultiSample = GetMultiSample();
if( 0 == nMultiSample )
{
class'UIAPI_COMBOBOX'.static.SYS_AddString( "OptionWnd.AABox", 869 );
class'UIAPI_WINDOW'.static.DisableWindow( "OptionWnd.AABox" );
}
else if( 1 == nMultiSample )
{
class'UIAPI_COMBOBOX'.static.SYS_AddString( "OptionWnd.AABox", 869 );
class'UIAPI_COMBOBOX'.static.SYS_AddString( "OptionWnd.AABox", 870 );
class'UIAPI_WINDOW'.static.EnableWindow( "OptionWnd.AABox" );
}
else if( 2 == nMultiSample )
{
class'UIAPI_COMBOBOX'.static.SYS_AddString( "OptionWnd.AABox", 869 );
class'UIAPI_COMBOBOX'.static.SYS_AddString( "OptionWnd.AABox", 870 );
class'UIAPI_COMBOBOX'.static.SYS_AddString( "OptionWnd.AABox", 871 );
class'UIAPI_WINDOW'.static.EnableWindow( "OptionWnd.AABox" );
}
bEnableEngSelection = IsEnableEngSelection();
Language = GetLanguage();
switch( Language )
{
case LANG_None:
break;
case LANG_Korean:
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "Korean" );
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "English" );
if( bEnableEngSelection )
class'UIAPI_WINDOW'.static.EnableWindow( "OptionWnd.LanguageBox" );
else
class'UIAPI_WINDOW'.static.DisableWindow( "OptionWnd.LanguageBox" );
break;
case LANG_English:
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "English" );
break;
case LANG_Japanese:
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "Japanese" );
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "English" );
if( bEnableEngSelection )
class'UIAPI_WINDOW'.static.EnableWindow( "OptionWnd.LanguageBox" );
else
class'UIAPI_WINDOW'.static.DisableWindow( "OptionWnd.LanguageBox" );
break;
case LANG_Taiwan:
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "Chinese(Taiwan)" );
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "English" );
if( bEnableEngSelection )
class'UIAPI_WINDOW'.static.EnableWindow( "OptionWnd.LanguageBox" );
else
class'UIAPI_WINDOW'.static.DisableWindow( "OptionWnd.LanguageBox" );
break;
case LANG_Chinese:
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "China" );
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "English" );
if( bEnableEngSelection )
class'UIAPI_WINDOW'.static.EnableWindow( "OptionWnd.LanguageBox" );
else
class'UIAPI_WINDOW'.static.DisableWindow( "OptionWnd.LanguageBox" );
break;
case LANG_Thai:
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "Thai" );
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "English" );
if( bEnableEngSelection )
class'UIAPI_WINDOW'.static.EnableWindow( "OptionWnd.LanguageBox" );
else
class'UIAPI_WINDOW'.static.DisableWindow( "OptionWnd.LanguageBox" );
break;
case LANG_Philippine:
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "English" );
break;
case LANG_Russia:
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "Russian" );
class'UIAPI_COMBOBOX'.static.AddString( "OptionWnd.LanguageBox", "English" );
if( bEnableEngSelection )
class'UIAPI_WINDOW'.static.EnableWindow( "OptionWnd.LanguageBox" );
else
class'UIAPI_WINDOW'.static.DisableWindow( "OptionWnd.LanguageBox" );
break;
default:
break;
}
if( CanUseHDR() )
{
class'UIAPI_COMBOBOX'.static.SYS_AddString( "OptionWnd.HDRBox", 1230 );
class'UIAPI_COMBOBOX'.static.SYS_AddString( "OptionWnd.HDRBox", 1231 );
class'UIAPI_COMBOBOX'.static.SYS_AddString( "OptionWnd.HDRBox", 1232 );
}
// 2007/11/16 Now new functions(LoadVideoOption,LoadAudioOption,LoadGameOption) load the ini configuration. - NeverDie
//InitVideoOption();
//InitAudioOption();
//InitGameOption();
LoadVideoOption();
LoadAudioOption();
LoadGameOption();
bShow = false;
}
function ApplyGameOption()
{
local int nSelectedNum;
local bool bChecked;
// ѕрѕој±ЕГ - LanguageBox
nSelectedNum = class'UIAPI_COMBOBOX'.static.GetSelectedNum( "OptionWnd.LanguageBox" );
if( 0 == nSelectedNum )
SetOptionBool( "Game", "IsNative", true );
else if( 1 == nSelectedNum )
SetOptionBool( "Game", "IsNative", false );
// АЪЅЕАМё§ - NameBox0
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.NameBox0" );
SetOptionBool( "Game", "MyName", bChecked );
// ёуЅєЕНАМё§ - NameBox1
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.NameBox1" );
SetOptionBool( "Game", "NPCName", bChecked );
// ЗчёНАМё§ - NameBox3
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.NameBox3" );
SetOptionBool( "Game", "PledgeMemberName", bChecked );
// ЖДЖјАМё§ - NameBox4
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.NameBox4" );
SetOptionBool( "Game", "PartyMemberName", bChecked );
// АП№ЭАМё§ - NameBox5
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.NameBox5" );
SetOptionBool( "Game", "OtherPCName", bChecked );
// ґЩёҐPCАМё§ - NameBox2
// ґЩёҐ АМё§ °ь·Г їЙјЗАМ ёрµО АыїлµЗ°н іЄј µ¤ѕоЅбѕЯ ЗП№З·О, Б¦АП іЄБЯїЎ ЗШѕЯЗСґЩ. - NeverDie
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.NameBox2" );
SetOptionBool( "Game", "GroupName", bChecked );
// ЕхёнИ - OpacityBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.OpacityBox" );
SetOptionBool( "Game", "TransparencyMode", bChecked );
// 3DИ»мЗҐ - ArrowBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.ArrowBox" );
SetOptionBool( "Game", "ArrowMode", bChecked );
// Д«ёЮ¶уГЯАы - CameraBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.CameraBox" );
SetOptionBool( "Game", "AutoTrackingPawn", bChecked );
// їЈЕНГ¤ЖГ - EnterChatBox
//~ bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.EnterChatBox" );
//~ SetOptionBool( "Game", "EnterChatting", bChecked );
// Г¤ЖГ±вИЈ - OldChatBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.OldChatBox" );
SetOptionBool( "Game", "OldChatting", bChecked );
// БцїЄёнЗҐЅГ - ZoneNameBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.ZoneNameBox" );
SetOptionBool( "Game", "ShowZoneTitle", bChecked );
// °ФАУЖБЗҐЅГ - GametipBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.GametipBox" );
SetOptionBool( "Game", "ShowGameTipMsg", bChecked );
// °бЕх °ЕєО - DuelBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.DuelBox" );
SetOptionBool( "Game", "IsRejectingDuel", bChecked );
// ЖДЖј ЅЕГ» °ЕєО - PartyRejectBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.PartyRejectBox" );
SetOptionBool( "Game", "IsRejectingParty", bChecked );
SetIgnorePartyInviting(bChecked );
//m_bPartyRejected = bChecked;
//ДїЗГ ЅЕГ» °ЕєО - CoupleActionBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.CoupleActionBox" );
SetOptionBool( "Game", "IsCoupleAction", bChecked );
//SetIgnorePartyInviting(bChecked );
// µе¶ш ѕЖАМЕЫ - DropItemBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.DropItemBox" );
SetOptionBool( "Game", "HideDropItem", bChecked );
// ЅГЅєЕЫ Ж©Едё®ѕу
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.SystemTutorialBox" );
SetOptionBool( "Game", "SystemTutorialBox", bChecked );
SetTutorialData(bChecked);
//PC№ж ЖчАОЖ® Іф±в - PCPointBox
// bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.PCPointBox" );
// SetOptionBool( "Game", "IsPCPointBox", bChecked );
// SetPCPointBoxData();
// АЇґП№цјі ЕшЖБ
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.UniversalToolTipBox" );
SetOptionBool( "Game", "UniversalToolTipBox", bChecked );
// АЇґП№цјі ЕшЖБ №ЪЅє µҐАМЕН јјЖГ
nSelectedNum = class'UIAPI_COMBOBOX'.static.GetSelectedNum( "OptionWnd.ToolTipPositionBox" );
SetOptionInt( "Game", "ToolTipPositionBox", nSelectedNum );
//~ SetToolTipData(GetOptionBool( "Game", "UniversalToolTipBox" ), GetOptionInt( "Game", "ToolTipPositionBox" ));
// ЖДЖј·зЖГ - LootingBox
if( class'UIAPI_WINDOW'.static.IsEnableWindow( "OptionWnd.LootingBox" ) )
{
nSelectedNum = class'UIAPI_COMBOBOX'.static.GetSelectedNum( "OptionWnd.LootingBox" );
SetOptionInt( "Game", "PartyLooting", nSelectedNum );
// Lootingtype = nSelectedNum;
}
// ±Ч·ЎЗИДїј - CursorBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.CursorBox" );
SetOptionBool( "Video", "UseColorCursor", bChecked );
//Background ЅЗЗајєґЙ і·ГЯ±в
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked("OptionWnd.LazyModeBox");
SetOptionBool( "Game", "UseLazyMode", bChecked);
//~ debug("·№АМБцёрµе"@ bChecked);
// ЅГЅєЕЫёЮЅГБцАьїлГў - SystemMsgBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.SystemMsgBox" );
SetOptionBool( "Game", "SystemMsgWnd", bChecked );
// µҐ№МБц - DamageBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.DamageBox" );
SetOptionBool( "Game", "SystemMsgWndDamage", bChecked );
// јТёрјєѕЖАМЕЫ»зїл - ItemBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.ItemBox" );
SetOptionBool( "Game", "SystemMsgWndExpendableItem", bChecked );
// °ФАУЖРµе - JoypadBox
if( CanUseJoystick() )
{
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.JoypadBox" );
SetOptionBool( "Game", "UseJoystick", bChecked );
}
//ё¶їмЅє їмЕ¬ёЇ - RightClickBox
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.RightClickBox" );
SetOptionBool( "Game", "RightClickBox", bChecked );
SetFixedDefaultCamera(bChecked);
// Е°єёµеєёѕИ - KeyboardBox
if( IsUseKeyCrypt() )
{
bChecked = class'UIAPI_CHECKBOX'.static.IsChecked( "OptionWnd.KeyboardBox" );
SetOptionBool("Game", "L2UseKeyCrypt", bChecked);
SetKeyCrypt( bChecked );
}
}
Наверное, л2екс там указьівается чтобьі определить директорию с файлами. ) В uc єта нативка в нвиндоу лежит (кстати, рекомендую поглядьівать туда, там куча полезной для интерфейса инфьі (все нативки, ивентьі, енумьі).вот я открываю l2.exe с помощью LUSE, нахожу в UIScript.uc нативку -
Код:native final function RequestBypassToServer( string strPass );
RegisterEvent( EV_LanguageChanged );
else if (Event_ID == EV_LanguageChanged)
{
HandleLanguageChanged(); //название от балдьі
}
ну либо свич, у корейцев где что
case EV_LanguageChanged:
HandleLanguageChanged();//название все еще от балдьі
break;
ExecuteCommand("/lang" @ LanguageInt);
Да я обратил внимание.Наверное, л2екс там указьівается чтобьі определить директорию с файлами. ) В uc єта нативка в нвиндоу лежит (кстати, рекомендую поглядьівать туда, там куча полезной для интерфейса инфьі (все нативки, ивентьі, енумьі).native final function RequestBypassToServer( string strPass );
Ну теперь благодаря Вам, так делать не буду, я просто сделал оперируя той информацией, которую знал на тот момент. Понимаю что это выход, но с ньюансами, доп поле в бд, доп действие клиента.хз нафига так делать, я бьі так не делал, но мало ли, сильно захочется
case EV_LanguageChanged:
nSelectedNum = class'UIAPI_COMBOBOX'.static.GetSelectedNum( "OptionWnd.LanguageBox" );
RequestBypassToServer("nSelectedNum");
break;
О, а я иответить не успел. )Так вроде решил проблему с компилом
я сделал регистрацию эвента в function OnRegisterEvent()
Какое-то из названий не верное, полагаю. )потом так в function OnRegisterEvent() :
Нет, єтот ивент сам тригернется при смене язьіка, вьізьівать его вручную не нужно (во всяком случае в єтой кейсе).А дальше я так понимаю мне нужно вызывать данный эвент?
Ой да, быстро писал, наверное не нажалось ctrl + c и я скопировал прошлое название, там function OnEvent( int a_EventID, String a_Param )Какое-то из названий не верное, полагаю. )