text:
using System;
using System.ComponentModel;
using System.Windows.Forms;
using JPB.RemoteAdmin.Server.Native.KeyAddon.WinApi;

namespace JPB.RemoteAdmin.Server.Native.KeyAddon.Controls
{
    ///
    /// This component monitors Application or Global input, depending on
	/// <see cref="MouseKeyEventProvider.Enabled"/> and provides appropriate
	/// events.
	///
    public class MouseKeyEventProvider : Component
    {
        private readonly KeyboardHookListener m_KeyboardHookManager;
        private readonly MouseHookListener m_MouseHookManager;

        ///
        /// Initializes a new instance of <see cref="MouseKeyEventProvider"/>
        ///
        public MouseKeyEventProvider()
        {
            m_KeyboardHookManager = new KeyboardHookListener(new GlobalHooker());
            m_MouseHookManager = new MouseHookListener(new GlobalHooker());
        }

        ///
        /// Gets or Sets the enabled status of the component.
        ///
        /// <value>
        /// True - The component is presently activated and will fire events.
        /// <para>
        /// False - The component is not active and will not fire events.
        /// </para>
        /// </value>
        public bool Enabled
        {
            get
            {
                return DesignMode
                           ? DesignTimeEnabled
                           : RunTimeEnabled;
            }
            set
            {
                if (DesignMode)
                {
                    DesignTimeEnabled = value;
                }
                else
                {
                    RunTimeEnabled = value;
                }
            }
        }

        private bool DesignTimeEnabled
        {
            get; set;
        }

        private bool RunTimeEnabled
        {
            get
            {
                return m_MouseHookManager.Enabled && m_KeyboardHookManager.Enabled;
            }
            set
            {
                m_MouseHookManager.Enabled = value;
                m_KeyboardHookManager.Enabled = value;
            }
        }

        ///
        /// Indicates which hooks to listen to application or global.
        ///
        public HookType HookType
        {
            get
            {
                return m_MouseHookManager.IsGlobal
                           ? HookType.Global
                           : HookType.Application;
            }
            set
            {
                Hooker hooker;
                switch (value)
                {
                    case HookType.Global:
                        hooker = new GlobalHooker();
                        break;

                    case HookType.Application:
                        hooker = new AppHooker();
                        break;

                    default:
                        return;
                }

                m_MouseHookManager.Replace(hooker);
                m_KeyboardHookManager.Replace(hooker);
            }
        }

        ///
        /// This component raises events. The value is always true.
        ///
        protected override bool CanRaiseEvents
        {
            get
            {
                return true;
            }
        }

        ///
        ///
        ///
        /// <param name="inputEvent"></param>
        /// <param name="e"></param>
        /// <remarks>
        /// Modified from http://stackoverflow.com/questions/1698889/raise-events-in-net-on-the-main-ui-thread
        /// </remarks>
        private void RaiseEventOnUIThread(Delegate inputEvent, EventArgs e)
        {
            object sender = this;
            foreach (Delegate d in inputEvent.GetInvocationList())
            {
                ISynchronizeInvoke syncer = d.Target as ISynchronizeInvoke;

                if (syncer == null)
                {
                    d.DynamicInvoke(new[] { sender, e });
                }
                else
                {
                    // I don't know if ASyncronous is really the way to go.
                    //  If the programmer wants to suppress input,
                    //  will asyncronous make that happen consistently?

                    //syncer.EndInvoke(syncer.BeginInvoke(inputEvent, new[] { sender, e }));
                    syncer.Invoke(inputEvent, new[] { sender, e });
                }
            }
        }

        //################################################################
        #region Mouse events

        private event MouseEventHandler m_MouseMove;
        ///
        /// Activated when the user moves the mouse.
        ///
        public event MouseEventHandler MouseMove
        {
            add
            {
                if (m_MouseMove == null)
                {
                    m_MouseHookManager.MouseMove += HookManager_MouseMove;
                }
                m_MouseMove += value;
            }

            remove
            {
                m_MouseMove -= value;
                if (m_MouseMove == null)
                {
                    m_MouseHookManager.MouseMove -= HookManager_MouseMove;
                }
            }
        }

        void HookManager_MouseMove(object sender, MouseEventArgs e)
        {
            if (m_MouseMove != null)
            {
                RaiseEventOnUIThread(m_MouseMove, e);
            }
        }

        private event MouseEventHandler m_MouseClick;
        ///
        /// Activated upon a single click of the mouse.
        ///
        public event MouseEventHandler MouseClick
        {
            add
            {
                if (m_MouseClick == null)
                {
                    m_MouseHookManager.MouseClick += HookManager_MouseClick;
                }
                m_MouseClick += value;
            }

            remove
            {
                m_MouseClick -= value;
                if (m_MouseClick == null)
                {
                    m_MouseHookManager.MouseClick -= HookManager_MouseClick;
                }
            }
        }

        void HookManager_MouseClick(object sender, MouseEventArgs e)
        {
            if (m_MouseClick != null)
            {
                RaiseEventOnUIThread(m_MouseClick, e);
            }
        }

        private event MouseEventHandler m_MouseDown;

        ///
        /// Activated when the user presses a mouse button.
        ///
        public event MouseEventHandler MouseDown
        {
            add
            {
                if (m_MouseDown == null)
                {
                    m_MouseHookManager.MouseDown += HookManager_MouseDown;
                }
                m_MouseDown += value;
            }

            remove
            {
                m_MouseDown -= value;
                if (m_MouseDown == null)
                {
                    m_MouseHookManager.MouseDown -= HookManager_MouseDown;
                }
            }
        }

        void HookManager_MouseDown(object sender, MouseEventArgs e)
        {
            if (m_MouseDown != null)
            {
                RaiseEventOnUIThread(m_MouseDown, e);
            }
        }

        private event MouseEventHandler m_MouseUp;

        ///
        /// Activated when the user releases a mouse button.
        ///
        public event MouseEventHandler MouseUp
        {
            add
            {
                if (m_MouseUp == null)
                {
                    m_MouseHookManager.MouseUp += HookManager_MouseUp;
                }
                m_MouseUp += value;
            }

            remove
            {
                m_MouseUp -= value;
                if (m_MouseUp == null)
                {
                    m_MouseHookManager.MouseUp -= HookManager_MouseUp;
                }
            }
        }

        void HookManager_MouseUp(object sender, MouseEventArgs e)
        {
            if (m_MouseUp != null)
            {
                RaiseEventOnUIThread(m_MouseUp, e);
            }
        }

        private event MouseEventHandler m_MouseDoubleClick;

        ///
        /// Activated when the user double-clicks with the mouse.
        ///
        public event MouseEventHandler MouseDoubleClick
        {
            add
            {
                if (m_MouseDoubleClick == null)
                {
                    m_MouseHookManager.MouseDoubleClick += HookManager_MouseDoubleClick;
                }
                m_MouseDoubleClick += value;
            }

            remove
            {
                m_MouseDoubleClick -= value;
                if (m_MouseDoubleClick == null)
                {
                    m_MouseHookManager.MouseDoubleClick -= HookManager_MouseDoubleClick;
                }
            }
        }

        void HookManager_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (m_MouseDoubleClick != null)
            {
                RaiseEventOnUIThread(m_MouseDoubleClick, e);
            }
        }

        private event EventHandler<MouseEventExtArgs> m_MouseMoveExt;

        ///
        /// Activated when the user moves the mouse.
        ///
        /// <remarks>
        /// This event provides extended arguments of type <see cref="MouseEventArgs"/> enabling you to
        /// supress further processing of mouse movement in other applications.
        /// </remarks>
        public event EventHandler<MouseEventExtArgs> MouseMoveExt
        {
            add
            {
                if (m_MouseMoveExt == null)
                {
                    m_MouseHookManager.MouseMoveExt += HookManager_MouseMoveExt;
                }
                m_MouseMoveExt += value;
            }

            remove
            {
                m_MouseMoveExt -= value;
                if (m_MouseMoveExt == null)
                {
                    m_MouseHookManager.MouseMoveExt -= HookManager_MouseMoveExt;
                }
            }
        }

        void HookManager_MouseMoveExt(object sender, MouseEventExtArgs e)
        {
            if (m_MouseMoveExt != null)
            {
                RaiseEventOnUIThread(m_MouseMoveExt, e);
            }
        }

        private event EventHandler<MouseEventExtArgs> m_MouseClickExt;
        ///
        /// Activated upon a single click of the mouse.
        ///
        /// <remarks>
        /// This event provides extended arguments of type <see cref="MouseEventArgs"/> enabling you to
        /// supress further processing of mouse click in other applications.
        /// </remarks>
        public event EventHandler<MouseEventExtArgs> MouseClickExt
        {
            add
            {
                // Disable warning that MouseClickExt is obsolete
#pragma warning disable 618
                if (m_MouseClickExt == null)
                {
                    m_MouseHookManager.MouseClickExt += HookManager_MouseClickExt;
                }
                m_MouseClickExt += value;
            }

            remove
            {
                m_MouseClickExt -= value;
                if (m_MouseClickExt == null)
                {
                    m_MouseHookManager.MouseClickExt -= HookManager_MouseClickExt;
                }
#pragma warning restore 618
            }
        }

        void HookManager_MouseClickExt(object sender, MouseEventExtArgs e)
        {
            if (m_MouseClickExt != null)
            {
                RaiseEventOnUIThread(m_MouseClickExt, e);
            }
        }

        private event EventHandler<MouseEventExtArgs> m_MouseDownExt;

        ///
        /// Activated when the user presses a mouse button.
        ///
        /// <remarks>
        /// This event provides extended arguments of type <see cref="MouseEventArgs"/> enabling you to
        /// supress further processing of mouse down in other applications.
        /// </remarks>
        public event EventHandler<MouseEventExtArgs> MouseDownExt
        {
            add
            {
                if (m_MouseDownExt == null)
                {
                    m_MouseHookManager.MouseDownExt += HookManager_MouseDownExt;
                }
                m_MouseDownExt += value;
            }

            remove
            {
                m_MouseDownExt -= value;
                if (m_MouseDownExt == null)
                {
                    m_MouseHookManager.MouseDownExt -= HookManager_MouseDownExt;
                }
            }
        }

        void HookManager_MouseDownExt(object sender, MouseEventExtArgs e)
        {
            if (m_MouseDownExt != null)
            {
                RaiseEventOnUIThread(m_MouseDownExt, e);
            }
        }

        private event EventHandler<MouseEventArgs> m_MouseWheel;
        ///
        /// Activated upon mouse scrolling.
        ///
        public event EventHandler<MouseEventArgs> MouseWheel
        {
            add
            {
                if (m_MouseWheel == null)
                {
                    m_MouseHookManager.MouseWheel += HookManager_MouseWheel;
                }
                m_MouseWheel += value;
            }

            remove
            {
                m_MouseWheel -= value;
                if (m_MouseWheel == null)
                {
                    m_MouseHookManager.MouseWheel -= HookManager_MouseWheel;
                }
            }
        }

        void HookManager_MouseWheel(object sender, MouseEventArgs e)
        {
            if (m_MouseWheel != null)
            {
                RaiseEventOnUIThread(m_MouseWheel, e);
            }
        }

        #endregion

        //################################################################
        #region Keyboard events

        private event KeyPressEventHandler m_KeyPress;

        ///
        /// Activated when the user presses a key.
        ///
        /// <remarks>
        /// Key events occur in the following order:
        /// <list type="number">
        /// <item>KeyDown</item>
        /// <item>KeyPress</item>
        /// <item>KeyUp</item>
        /// </list>
        ///The KeyPress event is not raised by noncharacter keys; however, the noncharacter keys do raise the KeyDown and KeyUp events.
        ///Use the KeyChar property to sample keystrokes at run time and to consume or modify a subset of common keystrokes.
        ///To handle keyboard events only in your application and not enable other applications to receive keyboard events,
        /// set the KeyPressEventArgs.Handled property in your form's KeyPress event-handling method to true.
        /// </remarks>
        public event KeyPressEventHandler KeyPress
        {
            add
            {
                if (m_KeyPress == null)
                {
                    m_KeyboardHookManager.KeyPress += HookManager_KeyPress;
                }
                m_KeyPress += value;
            }
            remove
            {
                m_KeyPress -= value;
                if (m_KeyPress == null)
                {
                    m_KeyboardHookManager.KeyPress -= HookManager_KeyPress;
                }
            }
        }

        void HookManager_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (m_KeyPress != null)
            {
                RaiseEventOnUIThread(m_KeyPress, e);
            }
        }

        private event KeyEventHandler m_KeyUp;

        ///
        /// Activated upon the release of a key.
        ///
        public event KeyEventHandler KeyUp
        {
            add
            {
                if (m_KeyUp == null)
                {
                    m_KeyboardHookManager.KeyUp += HookManager_KeyUp;
                }
                m_KeyUp += value;
            }
            remove
            {
                m_KeyUp -= value;
                if (m_KeyUp == null)
                {
                    m_KeyboardHookManager.KeyUp -= HookManager_KeyUp;
                }
            }
        }

        private void HookManager_KeyUp(object sender, KeyEventArgs e)
        {
            if (m_KeyUp != null)
            {
                RaiseEventOnUIThread(m_KeyUp, e);
            }
        }

        private event KeyEventHandler m_KeyDown;

        ///
        /// Activated when a key is pushed.
        ///
        public event KeyEventHandler KeyDown
        {
            add
            {
                if (m_KeyDown == null)
                {
                    m_KeyboardHookManager.KeyDown += HookManager_KeyDown;
                }
                m_KeyDown += value;
            }
            remove
            {
                m_KeyDown -= value;
                if (m_KeyDown == null)
                {
                    m_KeyboardHookManager.KeyDown -= HookManager_KeyDown;
                }
            }
        }

        private void HookManager_KeyDown(object sender, KeyEventArgs e)
        {
            RaiseEventOnUIThread(m_KeyDown, e);
        }

        #endregion

    }
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<TITLE>
ManagedEtmMonitorMBean (Java Execution Measurement Library)
</TITLE>

<META NAME="date" CONTENT="2009-03-12">

<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">

      Overview
      Package
    Class
      Use
      Tree
      Deprecated
      Index
      Help

 PREV CLASS
 NEXT CLASS

  FRAMES
 NO FRAMES

  All Classes

  SUMMARY: NESTED | FIELD | CONSTR | METHOD

DETAIL: FIELD | CONSTR | METHOD

etm.core.jmx

Interface ManagedEtmMonitorMBean

All Known Implementing Classes:
ManagedEtmMonitor

Deprecated. Please use EtmMonitorMBean and EtmMonitorJmxPlugin instead. Will be removed with JETM 2.0.0.

public interface ManagedEtmMonitorMBean

Etm Monitor MBean Interface.

Version:

$Revision: 98 $

Author:

void.fm

Method Summary

 java.lang.String[]
getAggregatorChain()

          Deprecated.

 java.util.Date
getLastResetTime()

          Deprecated.

 java.lang.String
getMonitorDescription()

          Deprecated.

 java.lang.String
getMonitorImplementationClass()

          Deprecated.

 java.util.Date
getStartTime()

          Deprecated.

 java.lang.String
getTimerDescription()

          Deprecated.

 java.lang.String
getTimerImplementationClass()

          Deprecated.

 long
getTimerTicksPerSecond()

          Deprecated.

 boolean
isStarted()

          Deprecated.

 void
reset()

          Deprecated.

 java.lang.String
showHtmlInfos()

          Deprecated.

 void
start()

          Deprecated.

 void
stop()

          Deprecated.

Method Detail

reset

void reset()

Deprecated.

getStartTime

java.util.Date getStartTime()

Deprecated.

getLastResetTime

java.util.Date getLastResetTime()

Deprecated.

getMonitorImplementationClass

java.lang.String getMonitorImplementationClass()

Deprecated.

getMonitorDescription

java.lang.String getMonitorDescription()

Deprecated.

getTimerImplementationClass

java.lang.String getTimerImplementationClass()

Deprecated.

getTimerDescription

java.lang.String getTimerDescription()

Deprecated.

getTimerTicksPerSecond

long getTimerTicksPerSecond()

Deprecated.

getAggregatorChain

java.lang.String[] getAggregatorChain()

Deprecated.

showHtmlInfos

java.lang.String showHtmlInfos()

Deprecated.

start

void start()

Deprecated.

stop

void stop()

Deprecated.

isStarted

boolean isStarted()

Deprecated.

      Overview
      Package
    Class
      Use
      Tree
      Deprecated
      Index
      Help

 PREV CLASS
 NEXT CLASS

  FRAMES
 NO FRAMES

  All Classes

  SUMMARY: NESTED | FIELD | CONSTR | METHOD

DETAIL: FIELD | CONSTR | METHOD

Copyright © 2004,2005, 2006, 2007 void.fm. All Rights Reserved.

redpajama_set_name: RedPajamaGithub


text:
/** Vector java bean entity **/
package dbbeans.traccion;
import java.sql.ResultSet;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Vector;

public class dbTRACCIONs {
	private Connection conn;
	private ResultSet rSet;
	private PreparedStatement stmt;
	private Vector result;

	public dbTRACCIONs() {
		super();
		result = new Vector();
	}
	public void setConnection(java.sql.Connection conn) {
		this.conn = conn;
	}
	public boolean find(String where) throws Exception, java.sql.SQLException {
		StringBuffer query = new StringBuffer();
		dbTRACCION TRACCION;
		query.append("SELECT * ");
		query.append("FROM TRACCION ");
		if (!where.equals("")){
			query.append("WHERE " + where );
		}
		stmt = conn.prepareStatement(query.toString().toLowerCase());
		rSet = stmt.executeQuery();

		while (rSet.next()) {
			TRACCION= new dbTRACCION();
			TRACCION.setSitraccion(rSet.getShort("sitraccion"));
			TRACCION.setVchdescripcion(rSet.getString("vchdescripcion"));
			result.addElement(TRACCION);
		}
		rSet.close();
		stmt.close();
		return false;
	}
	public void setResult (Vector result){
		this.result = result;
	}
	public Vector getResult(){
		return this.result;
	}
}


text:
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.

#include "OnlineSubsystemSteamPrivatePCH.h"
#include "OnlineSessionInterfaceSteam.h"
#include "OnlineSessionAsyncServerSteam.h"
#include "OnlineSubsystemSteam.h"
#include "IPAddressSteam.h"
#include "SteamSessionKeys.h"
#include "SteamUtilities.h"

#include "Engine.h"

/** Turn on Steam filter generation output */
#define DEBUG_STEAM_FILTERS 1

/** @TODO ONLINE Server values needed to advertise with Steam (NOTE: Steam expects UTF8) */
#define STEAMPRODUCTNAME "unrealdk"
#define STEAMGAMEDIR "unrealtest"
#define STEAMGAMEDESC "Unreal Test!"

/**
 * Get the engine unique build id as Steam key
 *
 * @return BuildUniqueId as an FString
 */
FString GetBuildIdAsSteamKey(const FOnlineSessionSettings& SessionSettings)
{
	return FString::Printf(TEXT("%s:%d"), UTF8_TO_TCHAR(STEAMKEY_BUILDUNIQUEID), SessionSettings.BuildUniqueId);
}

/**
 * Get the session flags bitfield as an FString
 *
 * @param SessionSettings settings to transform into string
 *
 * @return SessionFlags as an FString
 */
FString GetSessionFlagsAsString(const FOnlineSessionSettings& SessionSettings)
{
	int32 BitShift = 0;
	int32 SessionFlags = 0;
	// Some of this is redundant but included for completeness (bAntiCheatProtected, etc)
	SessionFlags |= (SessionSettings.bShouldAdvertise ? 1 : 0) << BitShift++;
	SessionFlags |= (SessionSettings.bAllowJoinInProgress ? 1 : 0) << BitShift++;
	SessionFlags |= (SessionSettings.bIsLANMatch ? 1 : 0) << BitShift++;
	SessionFlags |= (SessionSettings.bIsDedicated ? 1 : 0) << BitShift++;
	SessionFlags |= (SessionSettings.bUsesStats ? 1 : 0) << BitShift++;
	SessionFlags |= (SessionSettings.bAllowInvites ? 1 : 0) << BitShift++;
	SessionFlags |= (SessionSettings.bUsesPresence ? 1 : 0) << BitShift++;
	SessionFlags |= (SessionSettings.bAllowJoinViaPresence ? 1 : 0) << BitShift++;
	SessionFlags |= (SessionSettings.bAllowJoinViaPresenceFriendsOnly ? 1 : 0) << BitShift++;
	SessionFlags |= (SessionSettings.bAntiCheatProtected ? 1 : 0) << BitShift++;

	return FString::FromInt(SessionFlags);
}

/**
 *	Get all relevant FOnlineSessionSettings data as a series of Key,Value pairs
 *
 * @param SessionSettings session settings to get key, value pairs from
 * @param KeyValuePairs key value pair structure to add to
 */
void GetServerKeyValuePairsFromSessionSettings(const FOnlineSessionSettings& SessionSettings, FSteamSessionKeyValuePairs& KeyValuePairs, EOnlineDataAdvertisementType::Type AdvertisementType)
{
	//KeyValuePairs.Add(STEAMKEY_NUMPUBLICCONNECTIONS, FString::FromInt(SessionSettings.NumPublicConnections));
	//KeyValuePairs.Add(STEAMKEY_NUMPRIVATECONNECTIONS, FString::FromInt(SessionSettings.NumPrivateConnections));

	FString KeyStr;
	for (FSessionSettings::TConstIterator It(SessionSettings.Settings); It; ++It)
	{
		FName Key = It.Key();
		const FOnlineSessionSetting& Setting = It.Value();
		if (Setting.AdvertisementType == AdvertisementType)
		{
			if (SessionKeyToSteamKey(Key, Setting.Data, KeyStr))
			{
				FString SettingStr = Setting.Data.ToString();
				if (!SettingStr.IsEmpty())
				{
					KeyValuePairs.Add(KeyStr, SettingStr);
				}
				else
				{
					UE_LOG_ONLINE(Warning, TEXT("Empty session setting %s %s of type %s"), *Key.ToString(), *Setting.ToString(), EOnlineKeyValuePairDataType::ToString(Setting.Data.GetType()));
				}
			}
			else
			{
				UE_LOG_ONLINE(Warning, TEXT("Unsupported session setting %s %s of type %s"), *Key.ToString(), *Setting.ToString(), EOnlineKeyValuePairDataType::ToString(Setting.Data.GetType()));
			}
		}
	}
}

/**
 *	Get all relevant FSessionInfoSteam data as a series of Key,Value pairs
 *
 * @param SessionInfo session info to get key, value pairs from
 * @param KeyValuePairs key value pair structure to add to
 */
void GetServerKeyValuePairsFromSessionInfo(const FOnlineSessionInfoSteam* SessionInfo, FSteamSessionKeyValuePairs& KeyValuePairs)
{
	// @TODO ONLINE - not needed
	/*
	if (SessionInfo->HostAddr.IsValid())
	{
		uint32 HostAddr;
		SessionInfo->HostAddr->GetIp(HostAddr);
		KeyValuePairs.Add(STEAMKEY_HOSTIP, FString::FromInt(HostAddr));
		KeyValuePairs.Add(STEAMKEY_HOSTPORT, FString::FromInt(SessionInfo->HostAddr->GetPort()));
	}
	*/

	if (SessionInfo->SteamP2PAddr.IsValid())
	{
		TSharedPtr<FInternetAddrSteam> SteamAddr = StaticCastSharedPtr<FInternetAddrSteam>(SessionInfo->SteamP2PAddr);
		KeyValuePairs.Add(STEAMKEY_P2PADDR, SteamAddr->ToString(false));
		KeyValuePairs.Add(STEAMKEY_P2PPORT, FString::FromInt(SteamAddr->GetPort()));
	}
}

/**
 *	Get all relevant FSession data as a series of Key,Value pairs
 *
 * @param Session session data to get key, value pairs from
 * @param KeyValuePairs key value pair structure to add to
 */
void GetServerKeyValuePairsFromSession(const FOnlineSession* Session, FSteamSessionKeyValuePairs& KeyValuePairs)
{
	FUniqueNetIdSteam* SteamId = (FUniqueNetIdSteam*)(Session->OwningUserId.Get());
	FString OwningUserIdStr = SteamId->ToString();
	KeyValuePairs.Add(STEAMKEY_OWNINGUSERID, OwningUserIdStr);
	KeyValuePairs.Add(STEAMKEY_OWNINGUSERNAME, Session->OwningUserName);
	//KeyValuePairs.Add(STEAMKEY_NUMOPENPRIVATECONNECTIONS, FString::FromInt(Session->NumOpenPrivateConnections));
	//KeyValuePairs.Add(STEAMKEY_NUMOPENPUBLICCONNECTIONS, FString::FromInt(Session->NumOpenPublicConnections));
}

/**
 *  Update the backend with the currently defined settings
 *
 * @param World current running world instance
 * @param SessionName name of session to update published settings
 */
void UpdatePublishedSettings(UWorld* World, FNamedOnlineSession* Session)
{
	ISteamGameServer* SteamGameServerPtr = SteamGameServer();
	check(SteamGameServerPtr);

	// Copy the current settings so we can remove the ones used for well defined search parameters
	FOnlineSessionSettings TempSessionSettings = Session->SessionSettings;

	// Server name
	FString ServerName = Session->OwningUserName;
	SteamGameServerPtr->SetServerName(TCHAR_TO_UTF8(*ServerName));

	// Max user slots reported
	int32 NumTotalSlots = Session->SessionSettings.NumPublicConnections + Session->SessionSettings.NumPrivateConnections;
	SteamGameServerPtr->SetMaxPlayerCount(NumTotalSlots);

	// Region setting
	FString Region(TEXT(""));
	SteamGameServerPtr->SetRegion(TCHAR_TO_UTF8(*Region));

	// @TODO ONLINE Password protected or not
	SteamGameServerPtr->SetPasswordProtected(false);

	// Dedicated server or not
	SteamGameServerPtr->SetDedicatedServer(Session->SessionSettings.bIsDedicated ? true : false);

	// Map name
	FString MapName;
	if (TempSessionSettings.Get(SETTING_MAPNAME, MapName) && !MapName.IsEmpty())
	{
		SteamGameServerPtr->SetMapName(TCHAR_TO_UTF8(*MapName));
	}
	TempSessionSettings.Remove(SETTING_MAPNAME);

	// Bot Count
	int32 BotCount = 0;
	if (TempSessionSettings.Get(SETTING_NUMBOTS, BotCount))
	{
		SteamGameServerPtr->SetBotPlayerCount(BotCount);
	}
	TempSessionSettings.Remove(SETTING_NUMBOTS);

	// Update all the players names/scores
	if (World)
	{
		AGameState const* const GameState = World->GameState;
		if (GameState)
		{
			for (int32 PlayerIdx=0; PlayerIdx < GameState->PlayerArray.Num(); PlayerIdx++)
			{
				APlayerState const* const PlayerState = GameState->PlayerArray[PlayerIdx];
				if (PlayerState && PlayerState->UniqueId.IsValid())
				{
					CSteamID SteamId(*(uint64*)PlayerState->UniqueId->GetBytes());
					SteamGameServerPtr->BUpdateUserData(SteamId, TCHAR_TO_UTF8(*PlayerState->PlayerName), PlayerState->Score);
				}
			}
		}
	}

	// Get the advertised session settings out as Steam key/value pairs
	FSteamSessionKeyValuePairs AdvertisedKeyValuePairs;
	GetServerKeyValuePairsFromSession(Session, AdvertisedKeyValuePairs);

	if (Session->SessionInfo.IsValid())
	{
		FOnlineSessionInfoSteam* SessionInfo = (FOnlineSessionInfoSteam*)(Session->SessionInfo.Get());
		GetServerKeyValuePairsFromSessionInfo(SessionInfo, AdvertisedKeyValuePairs);
	}

	FString SessionFlags = GetSessionFlagsAsString(Session->SessionSettings);
	AdvertisedKeyValuePairs.Add(STEAMKEY_SESSIONFLAGS, SessionFlags);

	FString SessionBuildUniqueId = GetBuildIdAsSteamKey(Session->SessionSettings);

	GetServerKeyValuePairsFromSessionSettings(TempSessionSettings, AdvertisedKeyValuePairs, EOnlineDataAdvertisementType::ViaOnlineService);

	FSteamSessionKeyValuePairs AuxKeyValuePairs;
	GetServerKeyValuePairsFromSessionSettings(TempSessionSettings, AuxKeyValuePairs, EOnlineDataAdvertisementType::ViaPingOnly);

	FSteamSessionKeyValuePairs TempKeyValuePairs;
	GetServerKeyValuePairsFromSessionSettings(TempSessionSettings, TempKeyValuePairs, EOnlineDataAdvertisementType::ViaOnlineServiceAndPing);

	AdvertisedKeyValuePairs.Append(TempKeyValuePairs);
	AuxKeyValuePairs.Append(TempKeyValuePairs);

	FString GameTagsString, GameDataString;

	// Start the game tags with the build id so search results can early out
	GameTagsString = SessionBuildUniqueId;

	// Create the properly formatted Steam string (ie key:value,key:value,key) for GameTags/GameData
	FSteamSessionKeyValuePairs::TConstIterator It(AdvertisedKeyValuePairs);
	if (It)
	{
		UE_LOG_ONLINE(Verbose, TEXT("Master Server Data (%s, %s)"), *It.Key(), *It.Value());
		FString NewKey = FString::Printf(TEXT("%s:%s"), *It.Key(), *It.Value());

		if (GameTagsString.Len() + NewKey.Len() < k_cbMaxGameServerTags)
		{
			GameTagsString = GameTagsString + "," + NewKey;
		}
		else
		{
			UE_LOG_ONLINE(Warning, TEXT("Server setting %s overflows Steam SetGameTags call"), *NewKey);
		}

		if (NewKey.Len() < k_cbMaxGameServerGameData)
		{
			GameDataString = NewKey;
		}
		else
		{
			UE_LOG_ONLINE(Warning, TEXT("Server setting %s overflows Steam SetGameData call"), *NewKey);
		}

		++It;
	}
	for (; It; ++It)
	{
		UE_LOG_ONLINE(Verbose, TEXT("Master Server Data (%s, %s)"), *It.Key(), *It.Value());
		FString NewKey = FString::Printf(TEXT(",%s:%s"), *It.Key(), *It.Value());
		if (GameTagsString.Len() + NewKey.Len() < k_cbMaxGameServerTags)
		{
			GameTagsString += NewKey;
		}
		else
		{
			UE_LOG_ONLINE(Warning, TEXT("Server setting %s overflows Steam SetGameTags call"), *NewKey);
		}

		if (GameDataString.Len() + NewKey.Len() < k_cbMaxGameServerGameData)
		{
			GameDataString += NewKey;
		}
		else
		{
			UE_LOG_ONLINE(Warning, TEXT("Server setting %s overflows Steam SetGameData call"), *NewKey);
		}
	}

	// Small and searchable game tags (returned in initial server query structure)
	if (GameTagsString.Len() > 0 && GameTagsString.Len() < k_cbMaxGameServerTags)
	{
		UE_LOG_ONLINE(Verbose, TEXT("SetGameTags(%s)"), *GameTagsString);
		SteamGameServerPtr->SetGameTags(TCHAR_TO_UTF8(*GameTagsString));
	}

	// Large and searchable game data (never returned)
	if (GameDataString.Len() > 0 && GameDataString.Len() < k_cbMaxGameServerGameData)
	{
		UE_LOG_ONLINE(Verbose, TEXT("SetGameData(%s)"), *GameDataString);
		SteamGameServerPtr->SetGameData(TCHAR_TO_UTF8(*GameDataString));
	}

	// @TODO ONLINE - distinguish between server side keys (SetGameData()) and client side keys (SetKeyValue())
	// Set the advertised filter keys (these can not be filtered at master-server level, only client side)
	SteamGameServerPtr->ClearAllKeyValues();

	// Key value pairs sent as rules (requires secondary RulesRequest call)
	for (FSteamSessionKeyValuePairs::TConstIterator AdvKeyIt(AdvertisedKeyValuePairs); AdvKeyIt; ++AdvKeyIt)
	{
		UE_LOG_ONLINE(Verbose, TEXT("Aux Server Data (%s, %s)"), *AdvKeyIt.Key(), *AdvKeyIt.Value());
		SteamGameServerPtr->SetKeyValue(TCHAR_TO_UTF8(*AdvKeyIt.Key()), TCHAR_TO_UTF8(*AdvKeyIt.Value()));
	}

	// Key value pairs sent as rules (requires secondary RulesRequest call)
	for (FSteamSessionKeyValuePairs::TConstIterator AuxKeyIt(AuxKeyValuePairs); AuxKeyIt; ++AuxKeyIt)
	{
		UE_LOG_ONLINE(Verbose, TEXT("Aux Server Data (%s, %s)"), *AuxKeyIt.Key(), *AuxKeyIt.Value());
		SteamGameServerPtr->SetKeyValue(TCHAR_TO_UTF8(*AuxKeyIt.Key()), TCHAR_TO_UTF8(*AuxKeyIt.Value()));
	}
}

/**
 *	Get a human readable description of task
 */
FString FOnlineAsyncTaskSteamCreateServer::ToString() const
{
	return FString::Printf(TEXT("FOnlineAsyncTaskSteamCreateServer bWasSuccessful: %d"), bWasSuccessful);
}

/**
 * Give the async task time to do its work
 * Can only be called on the async task manager thread
 */
void FOnlineAsyncTaskSteamCreateServer::Tick()
{
	if (!bInit)
	{
		ISteamGameServer* SteamGameServerPtr = SteamGameServer();
		check(SteamGameServerPtr);

		UE_LOG_ONLINE(Verbose, TEXT("Initializing Steam game server"));

		SteamGameServerPtr->SetModDir(STEAMGAMEDIR);
		SteamGameServerPtr->SetProduct(STEAMPRODUCTNAME);
		SteamGameServerPtr->SetGameDescription(STEAMGAMEDESC);

		if (!SteamGameServerPtr->BLoggedOn())
		{
			// Login the server with Steam
			SteamGameServerPtr->LogOnAnonymous();
		}

		// Setup advertisement and force the initial update
		SteamGameServerPtr->SetHeartbeatInterval(-1);
		SteamGameServerPtr->EnableHeartbeats(true);
		SteamGameServerPtr->ForceHeartbeat();

		bInit = true;
	}

	// Wait for the connection and policy response callbacks
	FOnlineSessionSteamPtr SessionInt = StaticCastSharedPtr<FOnlineSessionSteam>(Subsystem->GetSessionInterface());
	if (SessionInt->bSteamworksGameServerConnected && SessionInt->GameServerSteamId->IsValid() && SessionInt->bPolicyResponseReceived)
	{
		bIsComplete = true;
		bWasSuccessful = true;
	}
	else
	{
		// Fallback timeout in case we don't hear from Steam
		if (GetElapsedTime() >= ASYNC_TASK_TIMEOUT)
		{
			bIsComplete = true;
			bWasSuccessful = false;
		}
	}
}

/**
 * Give the async task a chance to marshal its data back to the game thread
 * Can only be called on the game thread by the async task manager
 */
void FOnlineAsyncTaskSteamCreateServer::Finalize()
{
	FOnlineSessionSteamPtr SessionInt = StaticCastSharedPtr<FOnlineSessionSteam>(Subsystem->GetSessionInterface());
	if (bWasSuccessful)
	{
		FNamedOnlineSession* Session = SessionInt->GetNamedSession(SessionName);
		if (Session)
		{
			// Setup the host session info
			FOnlineSessionInfoSteam* NewSessionInfo = new FOnlineSessionInfoSteam(ESteamSession::AdvertisedSessionHost, *SessionInt->GameServerSteamId);
			NewSessionInfo->Init();

			ISteamGameServer* SteamGameServerPtr = SteamGameServer();
			check(SteamGameServerPtr);

			// Create the proper Steam P2P address for this machine
			NewSessionInfo->SteamP2PAddr = ISocketSubsystem::Get()->GetLocalBindAddr(*GLog);
			NewSessionInfo->SteamP2PAddr->SetPort(Subsystem->GetGameServerGamePort());
			UE_LOG_ONLINE(Verbose, TEXT("Server SteamP2P IP: %s"), *NewSessionInfo->SteamP2PAddr->ToString(true));

			// Create the proper ip address for this server
			NewSessionInfo->HostAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr(SteamGameServerPtr->GetPublicIP(), Subsystem->GetGameServerGamePort());
			UE_LOG_ONLINE(Verbose, TEXT("Server IP: %s"), *NewSessionInfo->HostAddr->ToString(true));

			if (!Session->OwningUserId.IsValid())
			{
				check(Session->SessionSettings.bIsDedicated);
				// Associate the dedicated server anonymous login as the owning user
				Session->OwningUserId = SessionInt->GameServerSteamId;
				Session->OwningUserName = Session->OwningUserId->ToString();
			}

			Session->SessionInfo = MakeShareable(NewSessionInfo);
			Session->SessionSettings.bAntiCheatProtected = SteamGameServerPtr->BSecure() != 0 ? true : false;

			Session->SessionState = EOnlineSessionState::Pending;

			UWorld* World = GetWorldForOnline(Subsystem->GetInstanceName());
			UpdatePublishedSettings(World, Session);

			SessionInt->RegisterLocalPlayers(Session);

			if (SteamUser())
			{
				SteamUser()->AdvertiseGame(NewSessionInfo->SessionId, SteamGameServerPtr->GetPublicIP(), Subsystem->GetGameServerGamePort());
			}

			// Set host rich presence string so we can find via FindFriendSesssion()
// 			FString ConnectionString = Sessions->GetSteamConnectionString(Session->SessionName);
// 			if (!SteamFriends()->SetRichPresence("connect", TCHAR_TO_UTF8(*ConnectionString)))
// 			{
// 				UE_LOG_ONLINE(Verbose, TEXT("Failed to set rich presence for session %s"), *Session->SessionName.ToString());
// 			}
		}
		else
		{
			UE_LOG_ONLINE(Warning, TEXT("No session %s found to update with Steam backend"), *SessionName.ToString());
		}
	}
	else
	{
		SessionInt->RemoveNamedSession(SessionName);
	}
}

/**
 *	Async task is given a chance to trigger it's delegates
 */
void FOnlineAsyncTaskSteamCreateServer::TriggerDelegates()
{
	IOnlineSessionPtr SessionInt = Subsystem->GetSessionInterface();
	if (SessionInt.IsValid())
	{
		SessionInt->TriggerOnCreateSessionCompleteDelegates(SessionName, bWasSuccessful);
	}
}

/**
 *	Get a human readable description of task
 */
FString FOnlineAsyncTaskSteamUpdateServer::ToString() const
{
	return FString::Printf(TEXT("FOnlineAsyncTaskSteamUpdateServer bWasSuccessful: %d Session: %s"),
		bWasSuccessful,
		*SessionName.ToString());
}

/**
 * Give the async task time to do its work
 * Can only be called on the async task manager thread
 */
void FOnlineAsyncTaskSteamUpdateServer::Tick()
{
	FOnlineSessionSteamPtr SessionInt = StaticCastSharedPtr<FOnlineSessionSteam>(Subsystem->GetSessionInterface());
	FNamedOnlineSession* Session = SessionInt->GetNamedSession(SessionName);
	if (Session)
	{
		bool bUsesPresence = Session->SessionSettings.bUsesPresence;
		if (bUsesPresence != NewSessionSettings.bUsesPresence)
		{
			UE_LOG_ONLINE(Warning, TEXT("Can't change presence settings on existing session %s, ignoring."), *SessionName.ToString());
		}

		Session->SessionSettings = NewSessionSettings;
		Session->SessionSettings.bUsesPresence = bUsesPresence;

		if (bUpdateOnlineData)
		{
			UWorld* World = GetWorldForOnline(Subsystem->GetInstanceName());

			// Master server update
			UpdatePublishedSettings(World, Session);
		}

		bWasSuccessful = true;
	}
	else
	{
		UE_LOG_ONLINE(Warning, TEXT("No session %s found to update with Steam backend"), *SessionName.ToString());
	}

	bIsComplete = true;
}

/**
 *	Async task is given a chance to trigger it's delegates
 */
void FOnlineAsyncTaskSteamUpdateServer::TriggerDelegates()
{
	IOnlineSessionPtr SessionInt = Subsystem->GetSessionInterface();
	if (SessionInt.IsValid())
	{
		SessionInt->TriggerOnUpdateSessionCompleteDelegates(SessionName, bWasSuccessful);
	}
}

/**
 *	Get a human readable description of task
 */
FString FOnlineAsyncTaskSteamLogoffServer::ToString() const
{
	return FString::Printf(TEXT("FOnlineAsyncTaskSteamLogoffServer bWasSuccessful: %d"), bWasSuccessful);
}

/**
 * Give the async task time to do its work
 * Can only be called on the async task manager thread
 */
void FOnlineAsyncTaskSteamLogoffServer::Tick()
{
	if (!bInit)
	{
		// @TODO ONLINE Listen Servers need to unset rich presence
		//SteamFriends()->SetRichPresence("connect", ""); for master server sessions
		SteamGameServer()->EnableHeartbeats(false);
		SteamGameServer()->LogOff();
		bInit = true;
	}

	// Wait for the disconnect
	FOnlineSessionSteamPtr SessionInt = StaticCastSharedPtr<FOnlineSessionSteam>(Subsystem->GetSessionInterface());
	if (!SessionInt->bSteamworksGameServerConnected && !SessionInt->GameServerSteamId.IsValid())
	{
		bIsComplete = true;
		bWasSuccessful = true;
	}
	else
	{
		// Fallback timeout in case we don't hear from Steam
		if (GetElapsedTime() >= ASYNC_TASK_TIMEOUT)
		{
			SessionInt->bSteamworksGameServerConnected = false;
			SessionInt->GameServerSteamId = NULL;
			bIsComplete = true;
			bWasSuccessful = false;
		}
	}
}

/**
 * Fills in the proxy search result with all the rules returned by the aux query
 *
 * @return true if session was successfully created, false otherwise
 */
bool FPendingSearchResultSteam::FillSessionFromServerRules()
{
	bool bSuccess = true;

	// Create the session info
	TSharedPtr<FOnlineSessionInfoSteam> SessionInfo = MakeShareable(new FOnlineSessionInfoSteam(ESteamSession::AdvertisedSessionClient, ServerId));
	TSharedRef<FInternetAddrSteam> SteamP2PAddr = MakeShareable(new FInternetAddrSteam);

	FOnlineSession* Session = &PendingSearchResult.Session;

	// Make sure we hit the important keys
	int32 KeysFound = 0;
	int32 SteamAddrKeysFound = 0;

	for (FSteamSessionKeyValuePairs::TConstIterator It(ServerRules); It; ++It)
	{
// 		if (FCStringAnsi::Stricmp(TCHAR_TO_ANSI(*It.Key()), STEAMKEY_NUMPUBLICCONNECTIONS) == 0)
// 		{
// 			Session->SessionSettings.NumPublicConnections = FCString::Atoi(*It.Value());
// 			KeysFound++;
// 		}
// 		else if (FCStringAnsi::Stricmp(TCHAR_TO_ANSI(*It.Key()), STEAMKEY_NUMPRIVATECONNECTIONS) == 0)
// 		{
// 			Session->SessionSettings.NumPrivateConnections = FCString::Atoi(*It.Value());
// 			KeysFound++;
// 		}
		if (FCStringAnsi::Stricmp(TCHAR_TO_ANSI(*It.Key()), STEAMKEY_SESSIONFLAGS) == 0)
		{
			int32 BitShift = 0;
			int32 SessionFlags = FCString::Atoi(*It.Value());
			Session->SessionSettings.bShouldAdvertise = (SessionFlags & (1 << BitShift++)) ? true : false;
			Session->SessionSettings.bAllowJoinInProgress = (SessionFlags & (1 << BitShift++)) ? true : false;
			Session->SessionSettings.bIsLANMatch = (SessionFlags & (1 << BitShift++)) ? true : false;
			Session->SessionSettings.bIsDedicated = (SessionFlags & (1 << BitShift++)) ? true : false;
			Session->SessionSettings.bUsesStats = (SessionFlags & (1 << BitShift++)) ? true : false;
			Session->SessionSettings.bAllowInvites = (SessionFlags & (1 << BitShift++)) ? true : false;
			Session->SessionSettings.bUsesPresence = (SessionFlags & (1 << BitShift++)) ? true : false;
			Session->SessionSettings.bAllowJoinViaPresence = (SessionFlags & (1 << BitShift++)) ? true : false;
			Session->SessionSettings.bAllowJoinViaPresenceFriendsOnly = (SessionFlags & (1 << BitShift++)) ? true : false;
			Session->SessionSettings.bAntiCheatProtected = (SessionFlags & (1 << BitShift++)) ? true : false;
			KeysFound++;
		}
		else if (FCStringAnsi::Stricmp(TCHAR_TO_ANSI(*It.Key()), STEAMKEY_OWNINGUSERID) == 0)
		{
			uint64 UniqueId = FCString::Atoi64(*It.Value());
			if (UniqueId != 0)
			{
				Session->OwningUserId = MakeShareable(new FUniqueNetIdSteam(UniqueId));
				KeysFound++;
			}
		}
		else if (FCStringAnsi::Stricmp(TCHAR_TO_ANSI(*It.Key()), STEAMKEY_OWNINGUSERNAME) == 0)
		{
			if (FCString::Strlen(*It.Value()) > 0)
			{
				Session->OwningUserName = It.Value();
				KeysFound++;
			}
		}
// 		else if (FCStringAnsi::Stricmp(TCHAR_TO_ANSI(*It.Key()), STEAMKEY_NUMOPENPRIVATECONNECTIONS) == 0)
// 		{
// 			Session->NumOpenPrivateConnections = FCString::Atoi(*It.Value());
// 			KeysFound++;
// 		}
// 		else if (FCStringAnsi::Stricmp(TCHAR_TO_ANSI(*It.Key()), STEAMKEY_NUMOPENPUBLICCONNECTIONS) == 0)
// 		{
// 			Session->NumOpenPublicConnections = FCString::Atoi(*It.Value());
// 			KeysFound++;
// 		}
		else if (FCStringAnsi::Stricmp(TCHAR_TO_ANSI(*It.Key()), STEAMKEY_P2PADDR) == 0)
		{
			uint64 SteamAddr = FCString::Atoi64(*It.Value());
			if (SteamAddr != 0)
			{
				SteamP2PAddr->SteamId.UniqueNetId = SteamAddr;
				SteamAddrKeysFound++;
			}
		}
		else if (FCStringAnsi::Stricmp(TCHAR_TO_ANSI(*It.Key()), STEAMKEY_P2PPORT) == 0)
		{
			int32 Port = FCString::Atoi(*It.Value());
			SteamP2PAddr->SetPort(Port);
			SteamAddrKeysFound++;
		}
		else
		{
			FName NewKey;
			FOnlineSessionSetting NewSetting;
			if (SteamKeyToSessionSetting(*It.Key(), TCHAR_TO_ANSI(*It.Value()), NewKey, NewSetting))
			{
				Session->SessionSettings.Set(NewKey, NewSetting);
			}
			else
			{
				bSuccess = false;
				UE_LOG_ONLINE(Warning, TEXT("Failed to parse setting from key %s value %s"), *It.Key(), *It.Value());
			}
		}
	}

	// Verify success with all required keys found
	if (bSuccess && (KeysFound == STEAMKEY_NUMREQUIREDSERVERKEYS) && (SteamAddrKeysFound == 2))
	{
		SessionInfo->HostAddr = HostAddr;

		if (SteamAddrKeysFound == 2)
		{
			SessionInfo->SteamP2PAddr = SteamP2PAddr;
		}

		Session->SessionInfo = SessionInfo;
		return true;
	}

	return false;
}

/**
 * Got data on a rule on the server -- you'll get one of these per rule defined on
 * the server you are querying
 */
void FPendingSearchResultSteam::RulesResponded(const char *pchRule, const char *pchValue)
{
	UE_LOG_ONLINE(Warning, TEXT("Rules response %s %s"), UTF8_TO_TCHAR(pchRule), UTF8_TO_TCHAR(pchValue));
	ParentQuery->ElapsedTime = 0.0f;
	ServerRules.Add(UTF8_TO_TCHAR(pchRule), UTF8_TO_TCHAR(pchValue));
}

/**
 * The server failed to respond to the request for rule details
 */
void FPendingSearchResultSteam::RulesFailedToRespond()
{
	UE_LOG_ONLINE(Warning, TEXT("Rules failed to respond for server"));
	ParentQuery->ElapsedTime = 0.0f;
	RemoveSelf();
}

/**
 *  The server has finished responding to the rule details request
 * (ie, you won't get anymore RulesResponded callbacks)
 */
void FPendingSearchResultSteam::RulesRefreshComplete()
{
	UE_LOG_ONLINE(Warning, TEXT("Rules refresh complete"));
	ParentQuery->ElapsedTime = 0.0f;

	// Only append this data if there is an existing search (NULL CurrentSessionSearch implies no active search query)
	FOnlineSessionSteamPtr SessionInt = StaticCastSharedPtr<FOnlineSessionSteam>(ParentQuery->Subsystem->GetSessionInterface());
	if (SessionInt.IsValid() && SessionInt->CurrentSessionSearch.IsValid() && SessionInt->CurrentSessionSearch->SearchState == EOnlineAsyncTaskState::InProgress)
	{
		if (FillSessionFromServerRules())
		{
			// Transfer rules to actual search results
			FOnlineSessionSearchResult* SearchResult = new (ParentQuery->SearchSettings->SearchResults) FOnlineSessionSearchResult(PendingSearchResult);
			SearchResult->Session.SessionInfo = PendingSearchResult.Session.SessionInfo;
			if (!SearchResult->IsValid())
			{
				// Remove the failed element
				ParentQuery->SearchSettings->SearchResults.RemoveAtSwap(ParentQuery->SearchSettings->SearchResults.Num() - 1);
			}
		}
	}

	RemoveSelf();
}

/**
 * Remove this search result from the parent's list of pending entries
 */
void FPendingSearchResultSteam::RemoveSelf()
{
	for (int32 SearchIdx=0; SearchIdx< ParentQuery->PendingSearchResults.Num(); SearchIdx++)
	{
		if (ParentQuery->PendingSearchResults[SearchIdx].ServerId == ServerId)
		{
			ParentQuery->PendingSearchResults.RemoveAtSwap(SearchIdx);
			break;
		}
	}
}

/**
 * Cancel this rules request
 */
void FPendingSearchResultSteam::CancelQuery()
{
	SteamMatchmakingServers()->CancelServerQuery(ServerQueryHandle);
}

/**
 *  Create the proper query for the master server based on the given search settings
 *
 * @param OutFilter Steam structure containing the proper filters
 * @param NumFilters number of filters contained in the array above
 */
void FOnlineAsyncTaskSteamFindServerBase::CreateQuery(MatchMakingKeyValuePair_t** OutFilter, int32& NumFilters)
{
	// Copy the params so we can remove the values as we use them
	FOnlineSearchSettings TempSearchSettings = SearchSettings->QuerySettings;

    // Include enough space for all search parameters plus the required one "gamedir" below
	int32 MaxFilters = TempSearchSettings.SearchParams.Num() + 1;

	*OutFilter = new MatchMakingKeyValuePair_t[MaxFilters];
	MatchMakingKeyValuePair_t* Filters = *OutFilter;

	int32 KeySize = sizeof(Filters[0].m_szKey);
	int32 ValueSize = sizeof(Filters[0].m_szValue);

    NumFilters = 0;
	// Filter must match at least our game
	FCStringAnsi::Strncpy(Filters[NumFilters].m_szKey, "gamedir", KeySize);
	FCStringAnsi::Strncpy(Filters[NumFilters].m_szValue, STEAMGAMEDIR, ValueSize);
	NumFilters++;

	FString MapName;
	if (TempSearchSettings.Get(SETTING_MAPNAME, MapName) && !MapName.IsEmpty())
	{
		// Server passes the filter if the server is playing the specified map.
		FCStringAnsi::Strncpy(Filters[NumFilters].m_szKey, "map", KeySize);
		FCStringAnsi::Strncpy(Filters[NumFilters].m_szValue, TCHAR_TO_ANSI(*MapName), ValueSize);
		NumFilters++;
	}
	TempSearchSettings.SearchParams.Remove(SETTING_MAPNAME);

	FString HostIp;
	if (TempSearchSettings.Get(SEARCH_STEAM_HOSTIP, HostIp) && !HostIp.IsEmpty())
	{
		// Server passes the filter if it passed a valid host ip.
		FCStringAnsi::Strncpy(Filters[NumFilters].m_szKey, "gameaddr", KeySize);
		FCStringAnsi::Strncpy(Filters[NumFilters].m_szValue, TCHAR_TO_ANSI(*HostIp), ValueSize);
		NumFilters++;
	}
	TempSearchSettings.SearchParams.Remove(SEARCH_STEAM_HOSTIP);

	int32 DedicatedOnly = 0;
	if (TempSearchSettings.Get(SEARCH_DEDICATED_ONLY, DedicatedOnly) && DedicatedOnly != 0)
	{
		// Server passes the filter if it passed true to SetDedicatedServer.
		FCStringAnsi::Strncpy(Filters[NumFilters].m_szKey, "dedicated", KeySize);
		FCStringAnsi::Strncpy(Filters[NumFilters].m_szValue, "true", ValueSize);
		NumFilters++;
	}
	TempSearchSettings.SearchParams.Remove(SEARCH_DEDICATED_ONLY);

	int32 SecureOnly = 0;
	if (TempSearchSettings.Get(SEARCH_SECURE_SERVERS_ONLY, SecureOnly) && SecureOnly != 0)
	{
		// Server passes the filter if the server is VAC-enabled.
		FCStringAnsi::Strncpy(Filters[NumFilters].m_szKey, "secure", KeySize);
		FCStringAnsi::Strncpy(Filters[NumFilters].m_szValue, "true", ValueSize);
		NumFilters++;
	}
	TempSearchSettings.SearchParams.Remove(SEARCH_SECURE_SERVERS_ONLY);

	int32 EmptyOnly = 0;
	if (TempSearchSettings.Get(SEARCH_EMPTY_SERVERS_ONLY, EmptyOnly) && EmptyOnly != 0)
	{
		// Server passes the filter if it doesn't have any players.
		FCStringAnsi::Strncpy(Filters[NumFilters].m_szKey, "noplayers", KeySize);
		FCStringAnsi::Strncpy(Filters[NumFilters].m_szValue, "true", ValueSize);
		NumFilters++;
	}
	TempSearchSettings.SearchParams.Remove(SEARCH_EMPTY_SERVERS_ONLY);

	// TEMP!!!!
	return;

	/**
	 * "full"		- not full
	 * "empty"		- not empty
	 * "proxy"		- a relay server
	 */
	if (NumFilters <= MaxFilters)
	{
		/** Filter out key value pairs */
		TArray<FString> Clauses;
		FString CurrentClause;
		for (FSearchParams::TConstIterator It(TempSearchSettings.SearchParams); It; ++It)
		{
			const FName Key = It.Key();
			const FOnlineSessionSearchParam& SearchParam = It.Value();

			FString KeyStr;
			if (SessionKeyToSteamKey(Key, SearchParam.Data, KeyStr))
			{
				if (SearchParam.ComparisonOp == EOnlineComparisonOp::Equals)
				{
					FString NewParam = FString::Printf(TEXT("%s:%s"), *KeyStr, *SearchParam.Data.ToString());
					if (NewParam.Len() <= ValueSize)
					{
						if (NewParam.Len() + CurrentClause.Len() < ValueSize)
						{
							if (CurrentClause.IsEmpty())
							{
								CurrentClause = NewParam;
							}
							else
							{
								// Continue to add to the clause
								CurrentClause = CurrentClause + "," + NewParam;
							}
						}
						else
						{
							// Create a new clause
							Clauses.Add(CurrentClause);
							CurrentClause = NewParam;
						}
					}
					else
					{
						UE_LOG_ONLINE(Warning, TEXT("Skipping search clause due to size: %s"), *NewParam);
					}
				}
			}
		}

		// Add the remainder clause
		if (!CurrentClause.IsEmpty())
		{
			Clauses.Add(CurrentClause);
		}

		if (Clauses.Num() > 0)
		{
			// Make sure there is room (Clauses + "and" clause if more than one)
			if (NumFilters + Clauses.Num() + (Clauses.Num() > 1 ? 1 : 0) <= MaxFilters)
			{
				if (Clauses.Num() > 1)
				{
					// "and" (x1 && x2 && ... && xn) where n is number of clauses
					FCStringAnsi::Strncpy(Filters[NumFilters].m_szKey, "and", KeySize);
					FCStringAnsi::Strncpy(Filters[NumFilters].m_szValue, TCHAR_TO_UTF8(*FString::FromInt(Clauses.Num())), ValueSize);
					NumFilters++;

					for (int32 ClauseIdx=0; ClauseIdx < Clauses.Num(); ClauseIdx++)
					{
						// Server passes the filter if the server's game data (ISteamGameServer::SetGameData) contains all of the
						// specified strings. The value field is a comma-delimited list of strings to match.
						FCStringAnsi::Strncpy(Filters[NumFilters].m_szKey, "gamedataand", KeySize);
						FCStringAnsi::Strncpy(Filters[NumFilters].m_szValue, TCHAR_TO_UTF8(*Clauses[ClauseIdx]), ValueSize);
						NumFilters++;
					}
				}
				else
				{
					// Server passes the filter if the server's game data (ISteamGameServer::SetGameData) contains all of the
					// specified strings. The value field is a comma-delimited list of strings to match.
					FCStringAnsi::Strncpy(Filters[NumFilters].m_szKey, "gamedataand", KeySize);
					FCStringAnsi::Strncpy(Filters[NumFilters].m_szValue, TCHAR_TO_UTF8(*Clauses[0]), ValueSize);
					NumFilters++;
				}
			}
		}
	}
}

/**
 *	Create a search result from a server response
 *
 * @param ServerDetails Steam server details
 */
void FOnlineAsyncTaskSteamFindServerBase::ParseSearchResult(class gameserveritem_t* ServerDetails)
{
	TSharedRef<FInternetAddr> ServerAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();

	ServerAddr->SetIp(ServerDetails->m_NetAdr.GetIP());
	ServerAddr->SetPort(ServerDetails->m_NetAdr.GetConnectionPort());
	int32 ServerQueryPort = ServerDetails->m_NetAdr.GetQueryPort();

	UE_LOG_ONLINE(Warning, TEXT("Server response IP:%s"), *ServerAddr->ToString(false));
	if (ServerDetails->m_bHadSuccessfulResponse)
	{
		FString GameTags(UTF8_TO_TCHAR(ServerDetails->m_szGameTags));

		// Check for build compatibility
		int32 ServerBuildId = 0;
		int32 BuildUniqueId = GetBuildUniqueId();

		TArray<FString> TagArray;
		GameTags.ParseIntoArray(TagArray, TEXT(","), true);
		if (TagArray.Num() > 0 && TagArray[0].StartsWith(STEAMKEY_BUILDUNIQUEID))
		{
			ServerBuildId = FCString::Atoi(*TagArray[0].Mid(ARRAY_COUNT(STEAMKEY_BUILDUNIQUEID)));
		}

		if (ServerBuildId != 0 && ServerBuildId == BuildUniqueId)
		{
			// Create a new pending search result
			FPendingSearchResultSteam* NewPendingSearch = new (PendingSearchResults) FPendingSearchResultSteam(this);
			NewPendingSearch->ServerId = FUniqueNetIdSteam(ServerDetails->m_steamID);
			NewPendingSearch->HostAddr = ServerAddr;

			// Fill search result members
			FOnlineSessionSearchResult* NewSearchResult = &NewPendingSearch->PendingSearchResult;
			NewSearchResult->PingInMs = FMath::Clamp(ServerDetails->m_nPing, 0, MAX_QUERY_PING);

			// Fill session members
			FOnlineSession* NewSession = &NewSearchResult->Session;

			//NewSession->OwningUserId = ;
			NewSession->OwningUserName = UTF8_TO_TCHAR(ServerDetails->GetName());

			NewSession->NumOpenPublicConnections = ServerDetails->m_nMaxPlayers - ServerDetails->m_nPlayers;
			NewSession->NumOpenPrivateConnections = 0;

			// Fill session settings members
			NewSession->SessionSettings.NumPublicConnections = ServerDetails->m_nMaxPlayers;
			NewSession->SessionSettings.NumPrivateConnections = 0;
			NewSession->SessionSettings.bAntiCheatProtected = ServerDetails->m_bSecure ? true : false;
			NewSession->SessionSettings.Set(SETTING_MAPNAME, FString(UTF8_TO_TCHAR(ServerDetails->m_szMap)), EOnlineDataAdvertisementType::ViaOnlineService);

			// Start a rules request for this new result
			NewPendingSearch->ServerQueryHandle = SteamMatchmakingServersPtr->ServerRules(ServerDetails->m_NetAdr.GetIP(), ServerQueryPort, NewPendingSearch);
			if (NewPendingSearch->ServerQueryHandle == HSERVERQUERY_INVALID)
			{
				// Remove the failed element
				PendingSearchResults.RemoveAtSwap(PendingSearchResults.Num() - 1);
			}
		}
		else
		{
			UE_LOG_ONLINE(Warning, TEXT("Removed incompatible build: ServerBuildUniqueId = 0x%08x, GetBuildUniqueId() = 0x%08x"),
				ServerBuildId, BuildUniqueId);
		}
	}
}

/**
 * Give the async task time to do its work
 * Can only be called on the async task manager thread
 */
void FOnlineAsyncTaskSteamFindServerBase::Tick()
{
	ISteamUtils* SteamUtilsPtr = SteamUtils();
	check(SteamUtilsPtr);

	if (!bInit)
	{
		SteamMatchmakingServersPtr = SteamMatchmakingServers();
		check(SteamMatchmakingServersPtr);

		int32 NumFilters = 0;
		MatchMakingKeyValuePair_t* Filters = NULL;
		CreateQuery(&Filters, NumFilters);

#if DEBUG_STEAM_FILTERS
		for (int32 FilterIdx=0; FilterIdx<NumFilters; FilterIdx++)
		{
			UE_LOG_ONLINE(Verbose, TEXT(" \"%s\" \"%s\" "), UTF8_TO_TCHAR(Filters[FilterIdx].m_szKey), UTF8_TO_TCHAR(Filters[FilterIdx].m_szValue));
		}
#endif

		ServerListRequestHandle = SteamMatchmakingServersPtr->RequestInternetServerList(Subsystem->GetSteamAppId(), &Filters, NumFilters, this);
		if (ServerListRequestHandle == NULL)
		{
			// Invalid API call
			bIsComplete = true;
			bWasSuccessful = false;
		}

		// Preallocate space for results
		PendingSearchResults.Empty(SearchSettings->MaxSearchResults);

		delete [] Filters;
		bInit = true;
	}

	ElapsedTime += 1.0f/16.0f;

	// Cancel query when we've reached our requested limit
	bool bReachedSearchLimit = (SearchSettings->SearchResults.Num() >= SearchSettings->MaxSearchResults) ? true : false;
	// Check for activity timeout
	bool bTimedOut = (ElapsedTime >= ASYNC_TASK_TIMEOUT) ? true : false;
	// Check for proper completion
	bool bServerSearchComplete = (bServerRefreshComplete && PendingSearchResults.Num() == 0) ? true : false;
	if ( bReachedSearchLimit || bTimedOut || bServerSearchComplete)
	{
		bIsComplete = true;
		bWasSuccessful = true;
	}

	if (bIsComplete)
	{
		// Cancel further server queries (may trigger RefreshComplete delegate)
		if (ServerListRequestHandle != NULL)
		{
			SteamMatchmakingServersPtr->CancelQuery(ServerListRequestHandle);
			SteamMatchmakingServersPtr->ReleaseRequest(ServerListRequestHandle);
			ServerListRequestHandle = NULL;
		}

		// Cancel further rules queries
		for (int32 PendingIdx=0; PendingIdx<PendingSearchResults.Num(); ++PendingIdx)
		{
			PendingSearchResults[PendingIdx].CancelQuery();
		}
		PendingSearchResults.Empty();
	}
}

/**
 * Called by the SteamAPI when a server has successfully responded
 */
void FOnlineAsyncTaskSteamFindServerBase::ServerResponded(HServerListRequest Request, int iServer)
{
	ElapsedTime = 0.0f;

	gameserveritem_t* Server = SteamMatchmakingServersPtr->GetServerDetails(Request, iServer);
	if (Server != NULL)
	{
		// Filter out servers that don't match our appid here
		if (!Server->m_bDoNotRefresh && Server->m_nAppID == SteamUtils()->GetAppID())
		{
			ParseSearchResult(Server);
		}
	}
}

/**
 * Called by the SteamAPI when a server has failed to respond
 */
void FOnlineAsyncTaskSteamFindServerBase::ServerFailedToRespond(HServerListRequest Request, int iServer)
{
	ElapsedTime = 0.0f;

	gameserveritem_t* Server = SteamMatchmakingServersPtr->GetServerDetails(Request, iServer);
	if (Server != NULL)
	{
		TSharedRef<FInternetAddr> ServerAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
		int32 ServerQueryPort = 0;

		ServerAddr->SetIp(Server->m_NetAdr.GetIP());
		ServerAddr->SetPort(Server->m_NetAdr.GetConnectionPort());
		ServerQueryPort = Server->m_NetAdr.GetQueryPort();

		UE_LOG_ONLINE(Warning, TEXT("Failed to respond IP:%s"), *ServerAddr->ToString(false));

		// Filter out servers that don't match our appid here
		if (Server->m_nAppID == SteamUtils()->GetAppID())
		{
		}
	}
}

/**
 * Called by the SteamAPI when all server requests for the list have completed
 */
void FOnlineAsyncTaskSteamFindServerBase::RefreshComplete(HServerListRequest Request, EMatchMakingServerResponse Response)
{
	UE_LOG_ONLINE(Verbose, TEXT("Server query complete %s"), *SteamMatchMakingServerResponseString(Response));
	bServerRefreshComplete = true;
	ElapsedTime = 0.0f;
}

/**
 * Give the async task a chance to marshal its data back to the game thread
 * Can only be called on the game thread by the async task manager
 */
void FOnlineAsyncTaskSteamFindServerBase::Finalize()
{
	FOnlineSessionSteamPtr SessionInt = StaticCastSharedPtr<FOnlineSessionSteam>(Subsystem->GetSessionInterface());

	SearchSettings->SearchState = bWasSuccessful ? EOnlineAsyncTaskState::Done : EOnlineAsyncTaskState::Failed;
	if (bWasSuccessful)
	{
		SearchSettings->SortSearchResults();
	}

	if (SessionInt->CurrentSessionSearch.IsValid() && SearchSettings == SessionInt->CurrentSessionSearch)
	{
		SessionInt->CurrentSessionSearch = NULL;
	}
}

/**
 *	Get a human readable description of task
 */
FString FOnlineAsyncTaskSteamFindServer::ToString() const
{
	return FString::Printf(TEXT("FOnlineAsyncTaskSteamFindServer bWasSuccessful: %d Results: %d"), bWasSuccessful, SearchSettings->SearchResults.Num());
}

/**
 *	Async task is given a chance to trigger it's delegates
 */
void FOnlineAsyncTaskSteamFindServer::TriggerDelegates()
{
	if (FindServerInviteCompleteDelegates.IsBound() && LocalUserNum >= 0)
	{
		if (bWasSuccessful && SearchSettings->SearchResults.Num() > 0)
		{
			if (bIsUsingNetIdDelegate)
			{
				FindServerInviteCompleteWithUserIdDelegates.Broadcast(bWasSuccessful, LocalUserNum, MakeShareable<FUniqueNetId>(new FUniqueNetIdSteam(SteamUser()->GetSteamID())), SearchSettings->SearchResults[0]);
			}
			else
			{
				FindServerInviteCompleteDelegates.Broadcast(LocalUserNum, bWasSuccessful, SearchSettings->SearchResults[0]);
			}

		}
		else
		{
			FOnlineSessionSearchResult EmptyResult;
			if (bIsUsingNetIdDelegate)
			{
				FindServerInviteCompleteWithUserIdDelegates.Broadcast(bWasSuccessful, LocalUserNum, MakeShareable<FUniqueNetId>(new FUniqueNetIdSteam(SteamUser()->GetSteamID())), EmptyResult);
			}
			else
			{
				FindServerInviteCompleteDelegates.Broadcast(LocalUserNum, bWasSuccessful, EmptyResult);
			}
		}
	}
}

/**
 *	Get a human readable description of task
 */
FString FOnlineAsyncTaskSteamFindServers::ToString() const
{
	return FString::Printf(TEXT("FOnlineAsyncTaskSteamFindServers bWasSuccessful: %d Results: %d"), bWasSuccessful, SearchSettings->SearchResults.Num());
}

/**
 *	Async task is given a chance to trigger it's delegates
 */
void FOnlineAsyncTaskSteamFindServers::TriggerDelegates()
{
	if (FindServersCompleteDelegates.IsBound())
	{
		FindServersCompleteDelegates.Broadcast(bWasSuccessful);
	}
}

/**
 * Give the async task a chance to marshal its data back to the game thread
 * Can only be called on the game thread by the async task manager
 */
void FOnlineAsyncEventSteamInviteAccepted::Finalize()
{
	FOnlineSessionSteamPtr SessionInt = StaticCastSharedPtr<FOnlineSessionSteam>(Subsystem->GetSessionInterface());
	if (SessionInt.IsValid() && !SessionInt->CurrentSessionSearch.IsValid())
	{
		// Create a search settings object
		TSharedRef<FOnlineSessionSearch> SearchSettings = MakeShareable(new FOnlineSessionSearch());
		SessionInt->CurrentSessionSearch = SearchSettings;
		SessionInt->CurrentSessionSearch->SearchState = EOnlineAsyncTaskState::InProgress;

		TCHAR ParsedURL[1024];
		if (!FParse::Value(*ConnectionURL, TEXT("SteamConnectIP="), ParsedURL, ARRAY_COUNT(ParsedURL)))
		{
			UE_LOG_ONLINE(Warning, TEXT("FOnlineAsyncEventSteamInviteAccepted: Failed to parse connection URL"));
			return;
		}

		// Determine the port
		int32 Port = 0;
		TCHAR* PortToken = FCString::Strchr(ParsedURL, ':');
		if (PortToken)
		{
			Port = FCString::Atoi(PortToken+1);
			PortToken[0] = '\0';
		}

		Port = (Port > 0) ? Port : Subsystem->GetGameServerGamePort();

		// Parse the address
		bool bIsValid;
		TSharedRef<FInternetAddr> IpAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
		IpAddr->SetIp(ParsedURL, bIsValid);
		if (bIsValid)
		{
			SessionInt->CurrentSessionSearch->QuerySettings.Set(FName(SEARCH_STEAM_HOSTIP), IpAddr->ToString(false), EOnlineComparisonOp::Equals);
			FOnlineAsyncTaskSteamFindServer* NewTask = new FOnlineAsyncTaskSteamFindServer(Subsystem, SearchSettings, LocalUserNum, SessionInt->OnSessionUserInviteAcceptedDelegates);
			Subsystem->QueueAsyncTask(NewTask);
		}
	}
	else
	{
		UE_LOG_ONLINE(Warning, TEXT("Invalid session or search already in progress when accepting invite.  Ignoring invite request."));
	}
}


text:
"use strict";

module.exports = function (sequelize, DataTypes) {

    var ShelfQuery = sequelize.define('shelfQuery', {
        number: {
            type: DataTypes.INTEGER
        },
        isClosed: {
            type: DataTypes.BOOLEAN,
            allowNull: false,
            defaultValue: false
        },
        itemCaption: {
            type: DataTypes.STRING
        },
        buy: {
            type: DataTypes.FLOAT
        },
        bought: {
            type: DataTypes.FLOAT
        },
        buyDate: {
            type: DataTypes.DATE
        },
        use: {
            type: DataTypes.FLOAT
        },
        used: {
            type: DataTypes.FLOAT
        },
        useDate: {
            type: DataTypes.DATE
        },
        spoil: {
            type: DataTypes.FLOAT
        },
        spoilDate: {
            type: DataTypes.DATE
        },
        comment: {
            type: DataTypes.TEXT
        }
    }, {
        paranoid: true,
        createdAt: false,
        associate: function (models) {
            ShelfQuery.belongsTo(models.user);
            ShelfQuery.belongsTo(models.measure);
            ShelfQuery.belongsTo(models.shelf);
            ShelfQuery.belongsTo(models.menu);
        }
    });

    return ShelfQuery;
};


text:
package engine.utils;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

/**
 * Simple efficient way to log messages used for debugging
 *
 * @author Brandon Porter
 *
 */
public final class Debug {
	public static boolean ENABLED = false;
	private static final DateFormat STAMP_FORMAT = new SimpleDateFormat("hh:mm:ss.SSS");

	// Static class
	private Debug() {
	}

	/**
	 * Prints out a message useful for debugging
	 *
	 * @param message
	 *            message to print to console
	 */
	public static void log(String message) {
		if (ENABLED)
			System.out.println(currentTimeStamp() + " [LOG] - " + message);
	}

	/**
	 * Prints out a warning message useful for debugging
	 *
	 * @param warning
	 *            warning to print to console
	 */
	public static void warn(String warning) {
		if (ENABLED)
			System.out.println(currentTimeStamp() + " [WARN] - " + warning);
	}

	/**
	 * PRintes out an error message useful for debugging
	 *
	 * @param error
	 *            error to print to console
	 */
	public static void error(String error) {
		System.err.println(currentTimeStamp() + " [ERROR] - " + error);
	}

	/*
	 * Returns the current time stamp of the message
	 */
	private static String currentTimeStamp() {
		return STAMP_FORMAT.format(System.currentTimeMillis());
	}
}


text:
<?php
include('../../static/general.php');
include('../../../static/general.php');

include('../../../xeditor/ckeditor_php5.php');

function get_product_how($post_product_alias){
   $conn   = connDB();

   $sql    = "SELECT * FROM tbl_product WHERE `product_alias` = '$post_product_alias'";
   $query  = mysql_query($sql, $conn);
   $result = mysql_fetch_array($query);

   return $result;
}

function get_how($post_product_id){
   $conn   = connDB();

   $sql    = "SELECT * FROM tbl_product_custom WHERE `product_id` = '$post_product_id'";
   $query  = mysql_query($sql, $conn);
   $result = mysql_fetch_array($query);

   return $result;
}

// DEFINED VARIABLE
$ajax_alias = $_POST['alias'];

// CALL FUNCTION
$data_product = get_product_how($ajax_alias);
$how          = get_how($data_product['id']);
?>

Content

Descriptions about your information.

              How To Use

                <?php
				$path = get_dirname($_SERVER['PHP_SELF']);
				$CKEditor = new CKEditor();
				$initialValue = $how['how'];
				$code = $CKEditor->editor("how", $initialValue);
				?>

              Technical Data

                <?php
				$path = get_dirname($_SERVER['PHP_SELF']);
				$CKEditor = new CKEditor();
				$initialValue = $how['technical'];
				$code = $CKEditor->editor("technical", $initialValue);
				?>


text:
package org.lwjgl.system;

import org.lwjgl.*;
import org.testng.*;
import org.testng.annotations.*;

import java.nio.*;
import java.nio.charset.*;
import java.util.*;
import java.util.function.*;

import static org.lwjgl.system.Checks.*;
import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.system.jni.JNINativeInterface.*;
import static org.testng.Assert.*;

@Test
public class MemoryUtilTest {

    public void testZeroAllocation() {
        if (!CHECKS) {
            throw new SkipException("This test may not run with checks disabled.");
        }

        long address = nmemAllocChecked(0);
        assertNotEquals(address, NULL);
        nmemFree(address);

        address = nmemCallocChecked(0, 0);
        assertNotEquals(address, NULL);
        nmemFree(address);

        address = nmemCallocChecked(1, 0);
        assertNotEquals(address, NULL);
        nmemFree(address);

        address = nmemCallocChecked(0, 8);
        assertNotEquals(address, NULL);
        nmemFree(address);

        address = nmemAlignedAllocChecked(16, 0);
        assertNotEquals(address, NULL);
        nmemAlignedFree(address);

        address = nmemReallocChecked(NULL, 0);
        assertNotEquals(address, NULL);
        address = nmemReallocChecked(address, 8);
        assertNotEquals(address, NULL);
        address = nmemReallocChecked(address, 0);
        assertNotEquals(address, NULL);
        nmemFree(address);
    }

    public void testOOME() {
        if (!CHECKS) {
            throw new SkipException("This test may not run with checks disabled.");
        }

        expectThrows(OutOfMemoryError.class, () -> nmemAllocChecked(-1L));
        expectThrows(OutOfMemoryError.class, () -> nmemCallocChecked(1, -1L));
    }

    public void testMemSet() {
        for (int size = 2; size <= (1 << 16); size <<= 1) {
            for (int offset = -1; offset <= 1; offset++) {
                ByteBuffer buffer = memAlloc(size + offset);
                for (int i = 0; i < buffer.capacity(); i++) {
                    buffer.put(i, (byte)0);
                }
                memSet(memAddress(buffer), 0x7F, buffer.capacity());
                for (int i = 0; i < buffer.capacity(); i++) {
                    assertEquals(buffer.get(i), 0x7F);
                }
                memFree(buffer);
            }

            for (int misalignment = 1; misalignment < 8; misalignment++) {
                ByteBuffer aligned = memAlloc(size + 8);
                for (int i = 0; i < aligned.capacity(); i++) {
                    aligned.put(i, (byte)0);
                }

                ByteBuffer buffer = memSlice(aligned, misalignment, size);
                memSet(memAddress(buffer), 0x7F, buffer.capacity());
                assertEquals(aligned.get(misalignment - 1), 0);
                for (int i = 0; i < buffer.capacity(); i++) {
                    assertEquals(buffer.get(i), 0x7F);
                }
                assertEquals(aligned.get(misalignment + size), 0);

                memFree(aligned);
            }
        }
    }

    public void testMemSetMisaligned() {
        long ref = nmemAlloc(16);
        long mem = nmemAlloc(16);
        for (int i = 0; i < 16; i++) {
            for (int j = 1; j <= (16 - i); j++) {
                // cannot trust the memSet in nmemCalloc yet
                memSetReference(ref, 0, 16);
                memSetReference(mem, 0, 16);

                // test misaligned memsets
                memSetReference(ref + i, 0xFF, j);
                memSet(mem + i, 0xFF, j);

                for (int k = 0; k < 16; k++) {
                    assertEquals(memGetByte(mem + k), memGetByte(ref + k));
                }
            }
        }
        nmemFree(mem);
        nmemFree(ref);
    }

    private static void memSetReference(long m, int value, int bytes) {
        for (int i = 0; i < bytes; i++) {
            memPutByte(m + i, (byte)(value & 0xFF));
        }
    }

    public void testMemCopy() {
        ByteBuffer src = BufferUtils.createByteBuffer(32);
        ByteBuffer dst = BufferUtils.createByteBuffer(32);

        for (int i = 0; i < src.capacity(); i++) {
            src.put(i, (byte)i);
        }

        memCopy(src, dst);

        for (int i = 0; i < src.capacity(); i++) {
            assertEquals(src.get(i), dst.get(i));
        }
    }

    public void testMemCopyMisaligned() {
        long src = nmemCalloc(1, 16);
        for (int i = 0; i < 16; i++) {
            memPutByte(src + i, (byte)i);
        }

        for (int i = 0; i < 16; i++) {
            for (int j = 0; j <= (16 - i); j++) {
                long ref = nmemCalloc(1, 16);
                long mem = nmemCalloc(1, 16);

                // test misaligned memcpys
                memCopyReference(src + i, ref + i, j);
                memCopy(src + i, mem + i, j);

                for (int k = 0; k < 16; k++) {
                    assertEquals(memGetByte(mem + k), memGetByte(ref + k));
                }

                nmemFree(mem);
                nmemFree(ref);
            }
        }

        nmemFree(src);
    }

    private static void memCopyReference(long src, long dst, int bytes) {
        for (int i = 0; i < bytes; i++) {
            memPutByte(dst + i, memGetByte(src + i));
        }
    }

    public void testJNINewBuffer() {
        ByteBuffer buffer = BufferUtils.createByteBuffer(32);
        for (int i = 0; i < buffer.capacity(); i++) {
            buffer.put(i, (byte)i);
        }

        long address = GetDirectBufferAddress(buffer);
        assertTrue(address != NULL);

        ByteBuffer view = Objects.requireNonNull(NewDirectByteBuffer(address + 8, 16));
        assertEquals(view.order(), ByteOrder.BIG_ENDIAN);
        for (int i = 0; i < view.capacity(); i++) {
            assertEquals(view.get(i), buffer.get(i + 8));
        }
    }

    public void testAddress() {
        ByteBuffer buffer = BufferUtils.createByteBuffer(32);
        for (int i = 0; i < buffer.capacity(); i++) {
            buffer.put(i, (byte)i);
        }

        long address = memAddress(buffer);
        assertTrue(address != NULL);

        buffer.position(8);
        buffer.limit(8 + 16);

        FloatBuffer floatView = memSlice(buffer).asFloatBuffer();

        assertEquals(address + 8, memAddress(floatView));
    }

    public void testDirectAccess() {
        ByteBuffer buffer = BufferUtils.createByteBuffer(40);

        long address = memAddress(buffer);

        for (int i = 0; i < buffer.capacity(); i++) {
            buffer.put(i, (byte)i);
        }

        for (int i = 0; i < buffer.capacity(); i++) {
            assertEquals(memGetByte(address + i), buffer.get(i));
        }

        for (int i = 0; i < buffer.capacity(); i++) {
            memPutByte(address + i, (byte)-i);
        }

        for (int i = 0; i < buffer.capacity(); i++) {
            assertEquals(-i, buffer.get(i));
        }

        memPutAddress(address, address);
        memPutDouble(address + 8, Math.PI);
        memPutLong(address + 16, Integer.MAX_VALUE * 2L);
        memPutFloat(address + 24, (float)Math.PI);
        memPutInt(address + 28, Short.MAX_VALUE * 2);
        memPutShort(address + 32, (short)(Byte.MAX_VALUE * 2));
        memPutByte(address + 34, (byte)127);

        assertEquals(memGetAddress(address), address);
        assertEquals(memGetDouble(address + 8), Math.PI);
        assertEquals(memGetLong(address + 16), Integer.MAX_VALUE * 2L);
        assertEquals(memGetFloat(address + 24), (float)Math.PI);
        assertEquals(memGetInt(address + 28), Short.MAX_VALUE * 2);
        assertEquals(memGetShort(address + 32), (short)(Byte.MAX_VALUE * 2));
        assertEquals(memGetByte(address + 34), (byte)127);
    }

    public void testNewBuffer() {
        ByteBuffer buffer = BufferUtils.createByteBuffer(32);
        for (int i = 0; i < buffer.capacity(); i++) {
            buffer.put(i, (byte)i);
        }

        long address = memAddress(buffer);
        assertTrue(address != NULL);

        ByteBuffer view = memByteBuffer(address + 8, 16);
        assertEquals(view.order(), ByteOrder.nativeOrder());
        for (int i = 0; i < view.capacity(); i++) {
            assertEquals(view.get(i), buffer.get(i + 8));
        }

        ShortBuffer sb = memShortBuffer(address, 16);
        assertEquals(sb.capacity(), 16);
        for (int i = 0; i < sb.capacity(); i++) {
            assertEquals(buffer.getShort(i << 1), sb.get(i));
        }

        IntBuffer ib = memIntBuffer(address, 8);
        assertEquals(ib.capacity(), 8);
        for (int i = 0; i < ib.capacity(); i++) {
            assertEquals(buffer.getInt(i << 2), ib.get(i));
        }

        LongBuffer lb = memLongBuffer(address, 4);
        assertEquals(lb.capacity(), 4);
        for (int i = 0; i < lb.capacity(); i++) {
            assertEquals(buffer.getLong(i << 3), lb.get(i));
        }

        FloatBuffer fb = memFloatBuffer(address, 8);
        assertEquals(fb.capacity(), 8);
        for (int i = 0; i < fb.capacity(); i++) {
            assertEquals(buffer.getFloat(i << 2), fb.get(i));
        }

        DoubleBuffer db = memDoubleBuffer(address, 4);
        assertEquals(db.capacity(), 4);
        for (int i = 0; i < db.capacity(); i++) {
            assertEquals(buffer.getDouble(i << 3), db.get(i));
        }
    }

    public void testViewBuffer() {
        IntBuffer ib = BufferUtils.createIntBuffer(10);
        ib.position(2);
        ib.limit(8);

        ByteBuffer bb = memByteBuffer(ib);
        assertEquals(bb.position(), 0);
        assertEquals(bb.limit(), 6 * Integer.BYTES);
        assertEquals(bb.remaining(), ib.remaining() * Integer.BYTES);

        for (int i = 0; i < ib.remaining(); i++) {
            assertEquals(bb.getInt(i * Integer.BYTES), 0);
        }
        memSet(ib, 0xFFFFFFFF);
        for (int i = 0; i < ib.remaining(); i++) {
            assertEquals(bb.getInt(i * Integer.BYTES), 0xFFFFFFFF);
        }
        memSet(bb, 0x0);
        for (int i = 0; i < ib.remaining(); i++) {
            assertEquals(ib.get(2 + i), 0x0);
        }

        DoubleBuffer db = memDoubleBuffer(memAddress(ib), Integer.MAX_VALUE);
        assertThrows(IllegalArgumentException.class, () -> memByteBuffer(db));

        db.limit(Integer.MAX_VALUE >> 3);
        assertEquals(memByteBuffer(db).remaining(), (Integer.MAX_VALUE >> 3) << 3);
    }

    @FunctionalInterface
    private interface BufferAddressGetter<T extends Buffer> {
        long apply(T buffer);
    }

    public void testDuplicateBuffer() {
        testDuplicateBuffer(memAlloc(32), it -> it.duplicate().order(it.order()), MemoryUtil::memDuplicate, ByteBuffer::order, MemoryUtil::memAddress);
        testDuplicateBuffer(memAllocShort(32), ShortBuffer::duplicate, MemoryUtil::memDuplicate, ShortBuffer::order, MemoryUtil::memAddress);
        testDuplicateBuffer(memAllocInt(32), IntBuffer::duplicate, MemoryUtil::memDuplicate, IntBuffer::order, MemoryUtil::memAddress);
        testDuplicateBuffer(memAllocLong(32), LongBuffer::duplicate, MemoryUtil::memDuplicate, LongBuffer::order, MemoryUtil::memAddress);
        testDuplicateBuffer(memAllocFloat(32), FloatBuffer::duplicate, MemoryUtil::memDuplicate, FloatBuffer::order, MemoryUtil::memAddress);
        testDuplicateBuffer(memAllocDouble(32), DoubleBuffer::duplicate, MemoryUtil::memDuplicate, DoubleBuffer::order, MemoryUtil::memAddress);
    }

    private static <T extends Buffer> void testDuplicateBuffer(
        T buffer,
        Function<T, T> duplicate,
        Function<T, T> memDuplicate,
        Function<T, ByteOrder> order,
        BufferAddressGetter<T> memAddress
    ) {
        buffer.mark();
        buffer.position(8);
        buffer.limit(16);

        T ref = duplicate.apply(buffer);
        T dup = memDuplicate.apply(buffer);

        assertEquals(order.apply(dup), order.apply(ref));
        assertEquals(memAddress.apply(dup), memAddress.apply(ref));
        assertEquals(dup.capacity(), ref.capacity());
        assertEquals(dup, ref);

        dup.reset();
        ref.reset();
        assertEquals(dup.position(), ref.position());

        memFree(buffer);
    }

    public void testSliceBuffer() {
        testSliceBuffer(memAlloc(32), it -> it.slice().order(it.order()), MemoryUtil::memSlice, ByteBuffer::order, MemoryUtil::memAddress);
        testSliceBuffer(memAllocShort(32), ShortBuffer::slice, MemoryUtil::memSlice, ShortBuffer::order, MemoryUtil::memAddress);
        testSliceBuffer(memAllocInt(32), IntBuffer::slice, MemoryUtil::memSlice, IntBuffer::order, MemoryUtil::memAddress);
        testSliceBuffer(memAllocLong(32), LongBuffer::slice, MemoryUtil::memSlice, LongBuffer::order, MemoryUtil::memAddress);
        testSliceBuffer(memAllocFloat(32), FloatBuffer::slice, MemoryUtil::memSlice, FloatBuffer::order, MemoryUtil::memAddress);
        testSliceBuffer(memAllocDouble(32), DoubleBuffer::slice, MemoryUtil::memSlice, DoubleBuffer::order, MemoryUtil::memAddress);
    }

    private static <T extends Buffer> void testSliceBuffer(
        T buffer,
        Function<T, T> slice,
        Function<T, T> memSlice,
        Function<T, ByteOrder> order,
        BufferAddressGetter<T> memAddress
    ) {
        buffer.position(8);
        buffer.limit(16);

        T ref = slice.apply(buffer);
        T dup = memSlice.apply(buffer);

        assertEquals(order.apply(dup), order.apply(ref));
        assertEquals(memAddress.apply(dup), memAddress.apply(ref));
        assertEquals(dup.capacity(), ref.capacity());
        assertEquals(dup, ref);

        memFree(buffer);
    }

    public void testSliceBufferAbs() {
        testSliceBufferAbs(
            memAlloc(32),
            it -> it.duplicate().order(it.order()),
            it -> it.slice().order(it.order()),
            MemoryUtil::memSlice,
            ByteBuffer::order,
            MemoryUtil::memAddress
        );
        testSliceBufferAbs(memAllocShort(32), ShortBuffer::duplicate, ShortBuffer::slice, MemoryUtil::memSlice, ShortBuffer::order, MemoryUtil::memAddress);
        testSliceBufferAbs(memAllocInt(32), IntBuffer::duplicate, IntBuffer::slice, MemoryUtil::memSlice, IntBuffer::order, MemoryUtil::memAddress);
        testSliceBufferAbs(memAllocLong(32), LongBuffer::duplicate, LongBuffer::slice, MemoryUtil::memSlice, LongBuffer::order, MemoryUtil::memAddress);
        testSliceBufferAbs(memAllocFloat(32), FloatBuffer::duplicate, FloatBuffer::slice, MemoryUtil::memSlice, FloatBuffer::order, MemoryUtil::memAddress);
        testSliceBufferAbs(memAllocDouble(32), DoubleBuffer::duplicate, DoubleBuffer::slice, MemoryUtil::memSlice, DoubleBuffer::order, MemoryUtil::memAddress);
    }

    @FunctionalInterface
    private interface AbsoluteSlicer<T extends Buffer> {
        T apply(T buffer, int offset, int capacity);
    }

    private static <T extends Buffer> void testSliceBufferAbs(
        T buffer,
        Function<T, T> duplicate,
        Function<T, T> slice,
        AbsoluteSlicer<T> memSlice,
        Function<T, ByteOrder> order,
        BufferAddressGetter<T> memAddress
    ) {
        buffer.position(4);

        T ref = sliceRef(buffer, 4, 12, duplicate, slice);
        T dup = memSlice.apply(buffer, 4, 12);

        assertEquals(order.apply(dup), order.apply(ref));
        assertEquals(memAddress.apply(dup), memAddress.apply(ref));
        assertEquals(dup.capacity(), ref.capacity());
        assertEquals(dup, ref);

        memFree(buffer);
    }

    private static <T extends Buffer> T sliceRef(T buffer, int offset, int capacity, Function<T, T> duplicate, Function<T, T> slice) {
        T copy = duplicate.apply(buffer);

        int position = buffer.position() + offset;
        copy.limit(position + capacity);
        copy.position(position);

        return slice.apply(copy);
    }

    public void testTextDecoding() {
        testTextDecoding(MemoryUtil::memASCII, MemoryUtil::memASCII, MemoryUtil::memASCII, 1);
        testTextDecoding(MemoryUtil::memUTF8, MemoryUtil::memUTF8, MemoryUtil::memUTF8, 1);
        testTextDecoding(MemoryUtil::memUTF16, MemoryUtil::memUTF16, MemoryUtil::memUTF16, 2);
    }

    @FunctionalInterface
    private interface TextEncoder {
        ByteBuffer apply(CharSequence text, boolean nullTerminated);
    }

    @FunctionalInterface
    private interface TextDecoder {
        String apply(ByteBuffer buffer, int length, int offset);
    }

    private static void testTextDecoding(TextEncoder encoder, Function<ByteBuffer, String> decoder, TextDecoder decoderUnsafe, int bpc) {
        ByteBuffer encoded = encoder.apply("one two three", true);

        assertEquals(encoded.position(), 0);
        assertEquals(encoded.remaining(), 14 * bpc);

        encoded.limit(13 * bpc);
        encoded.position(0 * bpc);
        assertEquals(decoder.apply(encoded), "one two three");

        encoded.limit(3 * bpc);
        encoded.position(0 * bpc);
        assertEquals(decoder.apply(encoded), "one");

        encoded.limit(7 * bpc);
        encoded.position(4 * bpc);
        assertEquals(decoder.apply(encoded), "two");

        encoded.limit(13 * bpc);
        encoded.position(8 * bpc);
        assertEquals(decoder.apply(encoded), "three");

        encoded.clear();

        assertEquals(decoderUnsafe.apply(encoded, 13, 0 * bpc), "one two three");
        assertEquals(decoderUnsafe.apply(encoded, 3, 0 * bpc), "one");
        assertEquals(decoderUnsafe.apply(encoded, 3, 4 * bpc), "two");
        assertEquals(decoderUnsafe.apply(encoded, 5, 8 * bpc), "three");

        memFree(encoded);
    }

    public void testUTF8() {
        // null-termination
        ByteBuffer bytes = memUTF8("");
        try {
            assertNotNull(bytes);
            assertEquals(bytes.remaining(), 1);
        } finally {
            memFree(bytes);
        }

        // no null-termination
        bytes = memUTF8("", false);
        try {
            assertNotNull(bytes);
            assertEquals(bytes.remaining(), 0);
        } finally {
            memFree(bytes);
        }

        // encode null returns null
        assertNull(memUTF8Safe((String)null));
        assertNull(memUTF8Safe(null, false));

        // decode null/NULL returns null
        assertNull(memUTF8Safe(NULL));
        assertNull(memUTF8Safe((ByteBuffer)null));

        // decode null/NULL with specific length/offset throws NPE
        try {
            //noinspection ConstantConditions
            memUTF8(null, 0);
            fail();
        } catch (NullPointerException ignored) {
        }

        try {
            //noinspection ConstantConditions
            memUTF8(null, 0, 0);
            fail();
        } catch (NullPointerException ignored) {
        }

        // decode non-null/NULL with length 0 returns empty string
        bytes = BufferUtils.createByteBuffer(4);
        bytes.limit(0);

        assertEquals(memUTF8(memAddress(bytes)), "");
        assertEquals(memUTF8(bytes, 0), "");
        assertEquals(memUTF8(bytes, 0, 0), "");

        // test boundary conditions

        CharBuffer chars = BufferUtils.createCharBuffer(2);

        testUTF8(bytes, chars, Character.MIN_CODE_POINT, 1);
        testUTF8(bytes, chars, 0x00000080, 2);
        testUTF8(bytes, chars, 0x00000800, 3);
        testUTF8(bytes, chars, 0x00010000, 4);

        testUTF8(bytes, chars, 0x0000007F, 1);
        testUTF8(bytes, chars, 0x000007FF, 2);
        testUTF8(bytes, chars, 0x0000FFFF, 3);
        testUTF8(bytes, chars, Character.MAX_CODE_POINT, 4);

        bytes.clear();

        memUTF8(new String(Character.toChars(0x0000D7FF)), false, bytes);
        assertEquals(bytes.get(0) & 0xFF, 0xED);
        assertEquals(bytes.get(1) & 0xFF, 0x9F);
        assertEquals(bytes.get(2) & 0xFF, 0xBF);

        memUTF8(new String(Character.toChars(0x0000E000)), false, bytes);
        assertEquals(bytes.get(0) & 0xFF, 0xEE);
        assertEquals(bytes.get(1) & 0xFF, 0x80);
        assertEquals(bytes.get(2) & 0xFF, 0x80);

        memUTF8(new String(Character.toChars(0x0000FFFD)), false, bytes);
        assertEquals(bytes.get(0) & 0xFF, 0xEF);
        assertEquals(bytes.get(1) & 0xFF, 0xBF);
        assertEquals(bytes.get(2) & 0xFF, 0xBD);

        memUTF8(new String(Character.toChars(0x0010FFFF)), false, bytes);
        assertEquals(bytes.get(0) & 0xFF, 0xF4);
        assertEquals(bytes.get(1) & 0xFF, 0x8F);
        assertEquals(bytes.get(2) & 0xFF, 0xBF);
        assertEquals(bytes.get(2) & 0xFF, 0xBF);
    }

    private static void testUTF8(ByteBuffer buffer, CharBuffer chars, int cp, int bytes) {
        char[] cpChars = Character.toChars(cp);

        chars.clear();
        chars.put(cpChars);
        chars.flip();

        buffer.clear();
        StandardCharsets.UTF_8
            .newEncoder()
            .encode(chars, buffer, true);
        buffer.flip();

        // test decoding
        assertEquals(buffer.remaining(), bytes);
        assertEquals(
            memUTF8(buffer, bytes),
            new String(cpChars)
        );

        ByteBuffer encoded = memUTF8(new String(cpChars), false);
        try {
            // test encoding
            assertEquals(encoded.remaining(), bytes);
            for (int i = 0; i < encoded.remaining(); i++) {
                assertEquals(
                    encoded.get(i),
                    buffer.get(i)
                );
            }
        } finally {
            memFree(encoded);
        }
    }

}


text:
"""SonarQube violations collector."""

from shared_data_model import DATA_MODEL

from collector_utilities.type import URL
from model import Entities, Entity, SourceMeasurement, SourceResponses

from .base import SonarQubeCollector

class SonarQubeViolations(SonarQubeCollector):
    """SonarQube violations metric. Also base class for metrics that measure specific rules."""

    rules_configuration = ""  # Subclass responsibility
    types_parameter = "types"

    async def _landing_url(self, responses: SourceResponses) -> URL:
        """Extend to add the issues path and parameters."""
        url = await super()._landing_url(responses)
        component = self._parameter("component")
        branch = self._parameter("branch")
        landing_url = f"{url}/project/issues?id={component}&resolved=false&branch={branch}"
        return URL(
            landing_url
            + self._query_parameter("severities")
            + self._query_parameter(self.types_parameter)
            + self.__rules_url_parameter()
        )

    async def _api_url(self) -> URL:
        """Extend to add the issue search path and parameters."""
        url = await super()._api_url()
        component = self._parameter("component")
        branch = self._parameter("branch")
        # If there's more than 500 issues only the first 500 are returned. This is no problem since we limit
        # the number of "entities" sent to the server anyway (that limit is 100 currently).
        api = f"{url}/api/issues/search?componentKeys={component}&resolved=false&ps=500&branch={branch}"
        return URL(
            api
            + self._query_parameter("severities")
            + self._query_parameter(self.types_parameter)
            + self.__rules_url_parameter()
        )

    def _query_parameter(self, parameter_key: str) -> str:
        """Return the multiple choice parameter as query parameter that can be passed to SonarQube."""
        values = ",".join(value.upper() for value in sorted(list(self._parameter(parameter_key))))
        return "" if values == self.__default_value(parameter_key) else f"&{parameter_key}={values}"

    def __rules_url_parameter(self) -> str:
        """Return the rules url parameter, if any."""
        rules = (
            DATA_MODEL.sources[self.source_type].configuration[self.rules_configuration].value
            if self.rules_configuration
            else []
        )
        return f"&rules={','.join(rules)}" if rules else ""

    async def _parse_source_responses(self, responses: SourceResponses) -> SourceMeasurement:
        """Override to parse the issues."""
        value = 0
        entities = Entities()
        for response in responses:
            json = await response.json()
            value += int(json.get("total", 0))
            entities.extend([await self._entity(issue) for issue in json.get("issues", [])])
        return SourceMeasurement(value=str(value), entities=entities)

    async def __issue_landing_url(self, issue_key: str) -> URL:
        """Generate a landing url for the issue."""
        url = await super()._landing_url(SourceResponses())
        component = self._parameter("component")
        branch = self._parameter("branch")
        return URL(f"{url}/project/issues?id={component}&issues={issue_key}&open={issue_key}&branch={branch}")

    async def _entity(self, issue) -> Entity:
        """Create an entity from an issue."""
        return Entity(
            key=issue["key"],
            url=await self.__issue_landing_url(issue["key"]),
            message=issue["message"],
            severity=issue.get("severity", "no severity").lower(),
            type=issue["type"].lower(),
            component=issue["component"],
            creation_date=issue["creationDate"],
            update_date=issue["updateDate"],
        )

    def __default_value(self, parameter_key: str) -> str:
        """Return the default value for the parameter."""
        defaults = DATA_MODEL.sources[self.source_type].parameters[parameter_key].values or []
        return ",".join(value.upper() for value in sorted(defaults))

class SonarQubeViolationsWithPercentageScale(SonarQubeViolations):
    """SonarQube violations collectors that support the percentage scale."""

    total_metric = ""  # Subclass responsibility

    async def _get_source_responses(self, *urls: URL, **kwargs) -> SourceResponses:
        """Extend to, next to the violations, get the total number of violations as basis for the percentage scale."""
        component = self._parameter("component")
        branch = self._parameter("branch")
        base_api_url = await SonarQubeCollector._api_url(self)  # pylint: disable=protected-access
        total_metric_api_url = URL(
            f"{base_api_url}/api/measures/component?component={component}&metricKeys={self.total_metric}&"
            f"branch={branch}"
        )
        return await super()._get_source_responses(*(urls + (total_metric_api_url,)), **kwargs)

    async def _parse_source_responses(self, responses: SourceResponses) -> SourceMeasurement:
        """Extend to parse the total number of violations."""
        measurement = await super()._parse_source_responses(responses)
        measures: list[dict[str, str]] = []
        for response in responses:
            measures.extend((await response.json()).get("component", {}).get("measures", []))
        measurement.total = str(sum(int(measure["value"]) for measure in measures))
        return measurement