Jump to content
Korean Random
denis79513

Отправка личных сообщений, создание взвода/роты

Recommended Posts

Сижу весь день, шарясь в декомпилированных исходниках питона. Нашел ClientChat.py вижу методы createChatChannel, findUsers, addFriend и с ними вроде бы все как понятно. 

Но как отправить приглашение во взвод/команду и простое сообщение? 

Edited by denis79513

Share this post


Link to post

Short link
Share on other sites

Решил идти по другому пути, нашел кнопку создания взвода в swf файлах, но как тут определить какой метод питона она вызывает по клику? Не вижу никаких евентов тут :

package net.wg.gui.lobby.header.headerButtonBar
{
    import flash.text.*;
    import net.wg.gui.components.controls.*;
    import net.wg.gui.events.*;
    import net.wg.gui.lobby.header.vo.*;
    import scaleform.clik.constants.*;

    public class HBC_Squad extends HeaderButtonContentItem
    {
        public var arrow:HBC_ArrowDown = null;
        public var textField:TextField = null;
        public var icon:UILoaderAlt = null;
        private var _squadDataVo:HBC_SquadDataVo = null;
        private static const ICON_ARROW_GAP:int = 3;
        private static const TEXT_ARROW_GAP:int = 14;
        private static const ARROW_RIGHT_PADDING:int = 4;

        public function HBC_Squad()
        {
            minScreenPadding.left = 13;
            minScreenPadding.right = 11;
            additionalScreenPadding.left = 4;
            additionalScreenPadding.right = -2;
            maxFontSize = 14;
            hideDisplayObjList.push(this.icon);
            return;
        }// end function

        override public function onPopoverClose() : void
        {
            this.arrow.state = HBC_ArrowDown.STATE_NORMAL;
            return;
        }// end function

        override public function onPopoverOpen() : void
        {
            this.arrow.state = HBC_ArrowDown.STATE_UP;
            return;
        }// end function

        override protected function configUI() : void
        {
            super.configUI();
            this.icon.addEventListener(UILoaderEvent.COMPLETE, this.onIconLoadCompleteHandler);
            this.icon.source = RES_ICONS.MAPS_ICONS_BATTLETYPES_40X40_SQUAD;
            return;
        }// end function

        override protected function updateSize() : void
        {
            if (this._squadDataVo.isEvent)
            {
                bounds.width = this.arrow.x + this.arrow.width + ARROW_RIGHT_PADDING;
            }
            else
            {
                bounds.width = this.icon.visible ? (this.icon.x + this.icon.width) : (this.textField.x + this.textField.width);
            }
            super.updateSize();
            return;
        }// end function

        override protected function updateData() : void
        {
            if (data)
            {
                this.textField.text = this._squadDataVo.buttonName;
            }
            else
            {
                this.textField.text = MENU.HEADERBUTTONS_BTNLABEL_CREATESQUAD;
            }
            if (this.isNeedUpdateFont())
            {
                updateFontSize(this.textField, useFontSize);
                needUpdateFontSize = false;
            }
            this.icon.source = this._squadDataVo.icon;
            this.textField.width = this.textField.textWidth + TEXT_FIELD_MARGIN;
            if (this.icon.visible)
            {
                this.icon.x = this.textField.width + ICON_MARGIN ^ 0;
                this.arrow.x = this.icon.x + this.icon.width + ICON_ARROW_GAP ^ 0;
            }
            else
            {
                this.arrow.x = this.textField.x + this.textField.textWidth + TEXT_ARROW_GAP ^ 0;
            }
            this.arrow.visible = this._squadDataVo.isEvent;
            super.updateData();
            return;
        }// end function

        override protected function onDispose() : void
        {
            this.icon.removeEventListener(UILoaderEvent.COMPLETE, this.onIconLoadCompleteHandler);
            this.textField = null;
            this.icon.dispose();
            this.icon = null;
            this._squadDataVo = null;
            this.arrow.dispose();
            this.arrow = null;
            super.onDispose();
            return;
        }// end function

        override protected function isNeedUpdateFont() : Boolean
        {
            return super.isNeedUpdateFont() || useFontSize != this.textField.getTextFormat().size;
        }// end function

        override public function set data(param1:Object) : void
        {
            this._squadDataVo = HBC_SquadDataVo(param1);
            super.data = param1;
            return;
        }// end function

        private function onIconLoadCompleteHandler(event:UILoaderEvent) : void
        {
            invalidate(InvalidationType.DATA, InvalidationType.SIZE);
            return;
        }// end function

    }
}

Share this post


Link to post

Short link
Share on other sites

как отправить приглашение во взвод

 

from gui.prb_control.dispatcher import g_prbLoader
from gui.prb_control.context import SendInvitesCtx
from gui.prb_control.settings import CTRL_ENTITY_TYPE

accountsToInvite = [12345, 45678, 639127]

functional = g_prbLoader.getDispatcher().getFunctional(CTRL_ENTITY_TYPE.UNIT)
if functional:
    functional.request(SendInvitesCtx(accountsToInvite, "Displayed invite text"))

  • Upvote 1

Share this post


Link to post

Short link
Share on other sites
from gui.prb_control.dispatcher import g_prbLoader
from gui.prb_control.context import SendInvitesCtx
from gui.prb_control.settings import CTRL_ENTITY_TYPE

accountsToInvite = [12345, 45678, 639127]

functional = g_prbLoader.getDispatcher().getFunctional(CTRL_ENTITY_TYPE.UNIT)
if functional:
    functional.request(SendInvitesCtx(accountsToInvite, "Displayed invite text")

Огромное спасибо! А я еще вот это нашел:

def prb_sendInvites(self, accountsToInvite, comment):
        if events.isPlayerEntityChanging:
            return
        self.base.accountPrebattle_sendPrebattleInvites(accountsToInvite, comment)

Это то же самое или нет? Предполагаю что это просто обертка над вашей функцией, или это что-то другое?

И что насчет создания взвода? Или если отправить приглашения он создается автоматически?

 

П.с. попробовал ваш код, ошибка в логе:  ERROR: AttributeError: 'NoneType' object has no attribute 'getFunctional'

 

Пробую вариант:

    accountsToInvite = [34751051]
    BigWorld.player().prb_sendInvites(accountsToInvite, "Message")

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

Edited by denis79513

Share this post


Link to post

Short link
Share on other sites

А я еще вот это нашел. Это то же самое или нет? Предполагаю что это просто обертка над вашей функцией, или это что-то другое?

 

Это собственно метод отправки внутри аккаунта, его можно вот так вызвать

BigWorld.player().prb_sendInvites([1234, 5434], "invite text")

Но не советую так делать, ибо перед отправкой приглашений, нужна проверка на cooldown а также permission.

Все это делается если использовать листинг, который я предоставил изначально.

 

П.с. попробовал ваш код, ошибка в логе:  ERROR: AttributeError: 'NoneType' object has no attribute 'getFunctional'

Для отправки нужно иметь созданный взвод/команду/вылазку/тренировочную комнату =)

 

 

Если у вас в планах рандомно вызывать этот метод, поменяйте код примерно на такой:

prbDispatcher = g_prbLoader.getDispatcher()
if prbDispatcher:
    functional = prbDispatcher.getFunctional(CTRL_ENTITY_TYPE.UNIT)
    if functional:
        functional.request(SendInvitesCtx(accountsToInvite, "Displayed invite text")

Share this post


Link to post

Short link
Share on other sites

Это собственно метод отправки внутри аккаунта, его можно вот так вызвать

BigWorld.player().prb_sendInvites([1234, 5434], "invite text")
Но не советую так делать, ибо перед отправкой приглашений, нужна проверка на cooldown а также permission.

Все это делается если использовать листинг, который я предоставил изначально.

 

 

Для отправки нужно иметь созданный взвод/команду/вылазку/тренировочную комнату =)

 

 

Если у вас в планах рандомно вызывать этот метод, поменяйте код примерно на такой:

prbDispatcher = g_prbLoader.getDispatcher()
if prbDispatcher:
    functional = prbDispatcher.getFunctional(CTRL_ENTITY_TYPE.UNIT)
    if functional:
        functional.request(SendInvitesCtx(accountsToInvite, "Displayed invite text")

 

Пока обновлял свое предыдущее сообщение, вы ответили, посмотреть пожалуйся сообщение выше. 

 

Это собственно метод отправки внутри аккаунта, его можно вот так вызвать

BigWorld.player().prb_sendInvites([1234, 5434], "invite text")
Но не советую так делать, ибо перед отправкой приглашений, нужна проверка на cooldown а также permission.

Все это делается если использовать листинг, который я предоставил изначально.

 

 

Для отправки нужно иметь созданный взвод/команду/вылазку/тренировочную комнату =)

 

 

Если у вас в планах рандомно вызывать этот метод, поменяйте код примерно на такой:

prbDispatcher = g_prbLoader.getDispatcher()
if prbDispatcher:
    functional = prbDispatcher.getFunctional(CTRL_ENTITY_TYPE.UNIT)
    if functional:
        functional.request(SendInvitesCtx(accountsToInvite, "Displayed invite text")

 

Если вы еще скажете как создать взвод, цены вам не будет))) Ну и я запилю одну классную штуку на основе этого.

Edited by denis79513

Share this post


Link to post

Short link
Share on other sites

что насчет создания взвода

 

Вот так можно создать взвод

from gui.prb_control.context import PrebattleAction
from gui.prb_control.dispatcher import g_prbLoader
from gui.prb_control.settings import PREBATTLE_ACTION_NAME

prbDispatcher = g_prbLoader.getDispatcher()
if prbDispatcher:
    prbDispatcher.doSelectAction(PrebattleAction(PREBATTLE_ACTION_NAME.SQUAD))

Share this post


Link to post

Short link
Share on other sites

@POLIROID,

Вот так можно создать взвод

from gui.prb_control.context import PrebattleAction
from gui.prb_control.dispatcher import g_prbLoader
from gui.prb_control.settings import PREBATTLE_ACTION_NAME

prbDispatcher = g_prbLoader.getDispatcher()
if prbDispatcher:
    prbDispatcher.doSelectAction(PrebattleAction(PREBATTLE_ACTION_NAME.SQUAD))

Итого все вместе: 

    prbDispatcher = g_prbLoader.getDispatcher()
    if prbDispatcher:
        prbDispatcher.doSelectAction(PrebattleAction(PREBATTLE_ACTION_NAME.SQUAD))
        functional = prbDispatcher.getFunctional(CTRL_ENTITY_TYPE.UNIT)
        if functional:
            functional.request(SendInvitesCtx(accountsToInvite, "Displayed invite text"))

Ошибок в логах нет, но ничего не происходит вообще, логично предположить что prbDispatcher почему то пустой??

Share this post


Link to post

Short link
Share on other sites

Ошибок в логах нет, но ничего не происходит вообще, логично предположить что prbDispatcher почему то пустой??

А вы в ангар то вошли? =)

Share this post


Link to post

Short link
Share on other sites

А вы в ангар то вошли? =)

Естественно) Для теста это все привязано к onBecomePlayer, остальной функционал срабатывает. И еще попутный вопрос, как проверить принадлежность к формированию? Чтобы делать эту проверку перед созданием формирования?

Edited by denis79513

Share this post


Link to post

Short link
Share on other sites

onBecomePlayer

Вот в чем проблема =)

Повесьте на кнопку и все заработает

Либо подпишитесь на g_playerEvents.onAccountShowGUI

Share this post


Link to post

Short link
Share on other sites

Вот в чем проблема =)

Повесьте на кнопку и все заработает

Либо подпишитесь на g_playerEvents.onAccountShowGUI

Повесил на g_playerEvents.onAccountShowGUI, то же самое, ошибок нет, ничего не происходит

Share this post


Link to post

Short link
Share on other sites

Посмотрел как работает PrebattleLoader

До загрузки ангара он бесполезен

 

Вот такой код будет работать

from gui.prb_control.context import PrebattleAction
from gui.prb_control.dispatcher import g_prbLoader
from gui.prb_control.settings import PREBATTLE_ACTION_NAME
from gui.shared import g_eventBus, events

def __onLobbyLoaded(event):
	prbDispatcher = g_prbLoader.getDispatcher()
	if prbDispatcher:
		prbDispatcher.doSelectAction(PrebattleAction(PREBATTLE_ACTION_NAME.SQUAD))

g_eventBus.addListener(events.GUICommonEvent.LOBBY_VIEW_LOADED, __onLobbyLoaded) 

Share this post


Link to post

Short link
Share on other sites

Посмотрел как работает PrebattleLoader

До загрузки ангара он бесполезен

 

Вот такой код будет работать

from gui.prb_control.context import PrebattleAction
from gui.prb_control.dispatcher import g_prbLoader
from gui.prb_control.settings import PREBATTLE_ACTION_NAME
from gui.shared import g_eventBus, events

def __onLobbyLoaded(event):
	prbDispatcher = g_prbLoader.getDispatcher()
	if prbDispatcher:
		prbDispatcher.doSelectAction(PrebattleAction(PREBATTLE_ACTION_NAME.SQUAD))

g_eventBus.addListener(events.GUICommonEvent.LOBBY_VIEW_LOADED, __onLobbyLoaded) 

Шикарно, благодарю. 

А можете еще подсказать, пытаюсь сделать фоновый процесс:

def OneTick(x):
    while True:
        SystemMessages.pushMessage("5 seconds", type=SystemMessages.SM_TYPE.Information)
        time.sleep(x)

def AddThread(self):
    parent(self)
    WotTeamWorker = threading.Thread(target=OneTick, args=(5000,))
    WotTeamWorker.start()
    Account.onBecomePlayer = parent

parent = Account.onBecomePlayer
Account.onBecomePlayer = AddThread

Но сообщение выводится только 1 раз. Хотя дополнительный процесс висит в диспетчере задач

Аааааа, чертов питон, во всех нормальных языках время в милисекундах а тут в секундах, и я пишу 5000...

 

Ладно, осталось по сути два вопроса: первый - проверка, состоит ли юзер в формировании, было бы неплохо если бы с этим кто помог, и второй, на какие события подписаться, чтобы гасить поток при начале боя, то есть нужно какое-то событие начало боя или клик по кнопке начала боя чтобы отрубить фоновый обработчик.

 

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

Edited by denis79513

Share this post


Link to post

Short link
Share on other sites

Аааааа, чертов питон, во всех нормальных языках время в милисекундах а тут в секундах, и я пишу 5000...

В Borland C тоже в секундах sleep, а вот delay уже в мс...

Но ваш код лучше делать через BigWorld.callback

Edited by SkepticalFox

Share this post


Link to post

Short link
Share on other sites

В Borland C тоже в секундах sleep, а вот delay уже в мс...

Но ваш код лучше делать через BigWorld.callback

JavaScript, С# в миллисекундах, php тоже вроде. Можете рассказать как пользоваться BigWorld.callback или отправьте куда нибудь, где написано.

Мне нужно чтобы процесс работал на фоне когда юзер в ангаре а когда в бою приостанавливался.

Share this post


Link to post

Short link
Share on other sites

Мне нужно чтобы процесс работал на фоне когда юзер в ангаре а когда в бою приостанавливался.

Если под процессом имеется ввиду поток тогда

 

import threading
from PlayerEvents import g_playerEvents

class Controller:
    
    def __init__(self):
        self.__available = threading.Event()
        self.__available.clear()
        self.__thread = threading.Thread(target=self.__mainLoop)
        self.__thread.setDaemon(True)
        self.__thread.start()
        g_playerEvents.onAccountBecomePlayer += self.__onAccountBecomePlayer
        g_playerEvents.onAccountBecomeNonPlayer += self.__onAccountBecomeNonPlayer
        
    def __mainLoop(self):
        while True:
            self.__available.wait()
            # This code works only when the player is PlayerAccount
    
    def __onAccountBecomePlayer(self):
        self.__available.set()
        
    def __onAccountBecomeNonPlayer(self):
        self.__available.clear()

g_ctrl = Controller()
 

 

Либо функциональная реализация

import threading
from PlayerEvents import g_playerEvents

def mainLoop():
    while True:
        available.wait()
        # This code works only when the player is PlayerAccount

def onAccountBecomePlayer():
    available.set()
    
def onAccountBecomeNonPlayer():
    available.clear()

available = threading.Event()
available.clear()

thread = threading.Thread(target=mainLoop)
thread.setDaemon(True)
thread.start()

g_playerEvents.onAccountBecomePlayer += onAccountBecomePlayer
g_playerEvents.onAccountBecomeNonPlayer += onAccountBecomeNonPlayer
Edited by POLIROID

Share this post


Link to post

Short link
Share on other sites

>Мне нужно чтобы процесс работал на фоне когда юзер в ангаре а когда в бою приостанавливался.

Тогда лучше использовать не onAccountBecomePlayer и onAccountBecomeNonPlayer а onAccountShowGUI и onAvatarBecomePlayer

Share this post


Link to post

Short link
Share on other sites

>Мне нужно чтобы процесс работал на фоне когда юзер в ангаре а когда в бою приостанавливался.

Тогда лучше использовать не onAccountBecomePlayer и onAccountBecomeNonPlayer а onAccountShowGUI и onAvatarBecomePlayer

Вы имели в виду onAccountShowGUI и onAccountBecomeNonPlayer? 

Share this post


Link to post

Short link
Share on other sites

>Вы имели в виду onAccountShowGUI и onAccountBecomeNonPlayer?

Нет именно:

onAccountShowGUI - событие когда в ангаре

onAvatarBecomePlayer - событие когда в бою

Share this post


Link to post

Short link
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...