• Welcome to Smashboards, the world's largest Super Smash Brothers community! Over 250,000 Smash Bros. fans from around the world have come to discuss these great games in over 19 million posts!

    You are currently viewing our boards as a visitor. Click here to sign up right now and start on your path in the Smash community!

Melee It On Me podcast! Join the MIOM Facebook Group!

Jaxel

Behind the Curtain...
Premium
Joined
Feb 5, 2009
Messages
310
Location
Edison, NJ
This is how I processed the TIO XML... If anyone does end up using this code; please give me credit. I've spent almost 4 years working with TIO and figuring out how to streamline the process. This is how my system currently stands. Originally, the code required to do what I do below was 10 times as big because it took a lot of work to reverse engineer nealdt's math.

PHP:
<?php

class EWRtorneo_Model_TioPro extends XenForo_Model
{
	public function uploadXmlFromFile($fileName)
	{
		if (!file_exists($fileName) || !is_readable($fileName))
		{
			throw new XenForo_Exception(new XenForo_Phrase('please_enter_valid_file_name_requested_file_not_read'), true);
		}

		try
		{
			$document = new SimpleXMLElement($fileName, 0, true);
		}
		catch (Exception $e)
		{
			throw new XenForo_Exception(new XenForo_Phrase('provided_file_was_not_valid_xml_file'), true);
		}

		if ($document->getName() != 'AppData')
		{
			throw new XenForo_Exception(new XenForo_Phrase('provided_file_was_not_valid_xml_file'), true);
		}
		
		$fileLoc = XenForo_Helper_File::getTempDir().'/tio'.XenForo_Visitor::getUserId().'.xml';
		copy($fileName, $fileLoc);

		$events = array(
			'name' => (string)$document->EventList->Event->Name,
			'host' => (string)$document->EventList->Event->Organizer,
			'venue' => (string)$document->EventList->Event->Location,
			'games' => array(),
		);
		
		foreach ($document->EventList->Event->Games->Game AS $game)
		{
			$events['games'][] = array(
				'ID' => (string) $game->ID,
				'name' => (string) $game->Name,
				'game' => (string) $game->GameName,
				'type' => (string) $game->BracketType,
				'entry' => (string) $game->EntryFee,
				'entries' => count($game->Entrants->children()),
				'final' => $game->InProgress == "True" ? false : true,
			);
		}

		return $events;
	}
	
	public function getEventDetails($gameID)
	{
		$fileLoc = XenForo_Helper_File::getTempDir().'/tio'.XenForo_Visitor::getUserId().'.xml';

		if (file_exists($fileLoc))
		{
			$xml = simplexml_load_file($fileLoc);
		}
		else
		{
			throw new XenForo_Exception(new XenForo_Phrase('please_enter_valid_file_name_requested_file_not_read'), true);
		}
		
		$event = $this->getEventInfo($xml, $gameID);
		$results = $this->getEventResults($xml, $gameID);
		
		return array($event, $results);
	}
	
	public function getEventInfo($xml, $gameID)
	{
		foreach ($xml->EventList->Event->Games->Game AS $game)
		{
			if ((string) $game->ID != $gameID) { continue; }
		
			$event = array(
				'event_name' => (string) $game->Name,
				'event_host' => (string) $xml->EventList->Event->Organizer,
				'event_venue' => (string) $xml->EventList->Event->Location,
				'event_date' => strtotime((string) $game->Date),
				'event_entry' => (int) $game->EntryFee,
				'event_service' => 'tiopro',
				'event_sval1' => (string) $xml->EventList->Event->ID,
				'event_sval2' => (string) $game->ID,
				'image_url' => false,
				'game' => (string) $game->GameName,
			);

			switch ((string) $game->BracketType)
			{
				case "SingleElim":		$event['event_type'] = "single";	break;
				case "DoubleElim":		$event['event_type'] = "double";	break;
				case "RoundRobin":		$event['event_type'] = "robin";		break;
			}
			
			break;
		}
		
		if (empty($event))
		{
			throw new XenForo_Exception(new XenForo_Phrase('tiopro_bracket_could_not_be_found'), true);
		}
		
		return $event;
	}
	
	public function getEventResults($xml, $gameID)
	{
		$players = array();
		
		foreach ($xml->PlayerList->Players->Player AS $player)
		{
			$players[(string)$player->ID] = array(
				'result_player' => (string)$player->Nickname,
				'result_user' => (int) $player->Name ? $this->getModelFromCache('XenForo_Model_User')->getUserById((int) $player->Name) : array(),
			);
		}

		foreach ($xml->EventList->Event->Games->Game AS $game)
		{
			if ((string)$game->ID != $gameID) { continue; }

			$matches = array();
			$bracket = (string) $game->BracketType;

			if ($bracket == 'RoundRobin')
			{
				foreach ($game->Bracket->Pools->Pool->Matches->Match AS $match)
				{
					$matches[] = $match;
				}
			}
			else
			{
				foreach ($game->Bracket->Matches->Match AS $match)
				{
					if ($match->IsWinners == 'True' && $match->IsChampionship == 'False' && $match->IsSecondChampionship == 'False') { continue; }

					if ((string)$match->IsSecondChampionship == 'True') { $number = 999; }
					elseif ((string)$match->IsChampionship == 'True') { $number = 998; }
					else { $number = (string)$match->Number; }

					$matches[$number] = $match;
				}
			}

			krsort($matches);
			
			break;
		}
		
		if (empty($matches))
		{
			throw new XenForo_Exception(new XenForo_Phrase('tiopro_bracket_still_in_progress'), true);
		}
	
		switch ($bracket)
		{
			case "SingleElim":		
			case "DoubleElim":		$results = $this->calculateElim($matches, $players);		break;
			case "RoundRobin":		$results = $this->calculateRobin($matches, $players);		break;
		}

		foreach ($results AS &$result)
		{
			$result['result_ordinal'] = $this->getModelFromCache('EWRtorneo_Model_Results')->addOrdinal($result['result_rank']);
		}
		
		return $results;
	}
	
	public function calculateRobin($matches, $players)
	{
		$results = array();
		
		foreach ($matches AS $match)
		{
			if (empty($players[(string)$match->Winner]))
			{
				throw new XenForo_Exception(new XenForo_Phrase('tiopro_bracket_still_in_progress'), true);
			}

			if ((string)$match->Winner == (string)$match->Player1)
			{
				$winner = (string)$match->Player1;
				$loser = (string)$match->Player2;
			}
			else
			{
				$winner = (string)$match->Player2;
				$loser = (string)$match->Player1;
			}
			
			if (empty($results[$winner]))
			{
				$results[$winner] = $players[$winner] + array('wins' => 0, 'loss' => 0, 'winsR' => 0, 'lossR' => 0);
			}
			
			if (empty($results[$loser]))
			{
				$results[$loser] = $players[$loser] + array('wins' => 0, 'loss' => 0, 'winsR' => 0, 'lossR' => 0);
			}
			
			if ((string)$match->SetType == 'TotalOf')
			{
				$loss = (int)$match->Losses;
				$wins = (int)$match->Games - $loss;
			}
			else
			{
				$loss = (int)$match->Losses;
				$wins = ceil((int)$match->Games / 2);
			}
			
			$results[$winner]['wins']++;
			$results[$winner]['winsR'] += $wins;
			$results[$winner]['lossR'] += $loss;
			
			$results[$loser]['loss']++;
			$results[$loser]['winsR'] += $loss;
			$results[$loser]['lossR'] += $wins;
		}
		
		uasort($results, create_function('$a, $b', '
			if ($a["wins"] > $b["wins"]) { return -1; }
			else if ($a["wins"] < $b["wins"]) { return 1; }
			
			if ($a["loss"] > $b["loss"]) { return 1; }
			else if ($a["loss"] < $b["loss"]) { return -1; }
			
			if ($a["winsR"] > $b["winsR"]) { return -1; }
			else if ($a["winsR"] < $b["winsR"]) { return 1; }
			
			if ($a["lossR"] > $b["lossR"]) { return 1; }
			else if ($a["lossR"] < $b["lossR"]) { return -1; }
		'));
		
		$rank = 0;
		$step = 1;
		$wins = 0;
		$loss = 0;
		$winsR = 0;
		$lossR = 0;
		
		foreach ($results AS &$result)
		{
			if ($wins == $result['wins'] && $loss == $result['loss'] && $winsR == $result['winsR'] && $lossR == $result['lossR'])
			{
				$step++;
			}
			else
			{
				$wins = $result['wins'];
				$loss = $result['loss'];
				$winsR = $result['winsR'];
				$lossR = $result['lossR'];
				
				$rank = $rank + $step;
				$step = 1;
			}
			
			$result['result_rank'] = $rank;
		}
		
		return $results;
	}
	
	public function calculateElim($matches, $players)
	{
		$results = array();
		$champ = false;
		$rank = 1;
		$step = 1;
		
		if (empty($players[(string)$matches[998]->Winner]))
		{
			throw new XenForo_Exception(new XenForo_Phrase('tiopro_bracket_still_in_progress'), true);
		}

		foreach ($matches AS $match)
		{
			if (!empty($players[(string)$match->Player1]) && !empty($players[(string)$match->Player2]))
			{
				if ((string)$match->Winner == (string)$match->Player1)
				{
					$winner = (string)$match->Player1;
					$loser = (string)$match->Player2;
				}
				else
				{
					$winner = (string)$match->Player2;
					$loser = (string)$match->Player1;
				}

				if (!$champ)
				{
					$results[] = $players[$winner] + array('result_rank' => $rank);
					$champ = true;
					$rank++;
				}
				elseif ($match->IsChampionship == 'True')
				{
					continue;
				}

				$results[] = $players[$loser] + array('result_rank' => $rank);

				if ((int)$match->PrevSiblingMatch >= 0)
				{
					$step++;
				}
				else
				{
					$rank = $rank + $step;
					$step = 1;
				}
			}
		}
		
		return $results;
	}
}
I do agree that Challonge's only advantage is that it is online; if TIO was online, that advantage would disappear.
 

Scar

#HarveyDent
Joined
Feb 11, 2007
Messages
6,066
Location
Sunnyvale, CA
Next one announced! Doin' it Wednesday!

Agenda is forthcoming.

Anyhoo, great job with the podcast Bobby. Let's get Sheridan's sexy mug on the video too.
I bought him a webcam for the holidays but he's not coming to our New Year's Shindig so I can't give it to him - FOILED AGAIN!
 

pockyD

Smash Legend
Joined
Jul 21, 2006
Messages
11,926
Location
San Francisco, CA
ya ether you would tune in bc scar whooped you at rom 5 LOOOOOOOOOOOL

sorry i refuse to sully pocky d's good name

it's scar

ROFL HAPPY NEW YEAR EVEYRONE

LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOL
 

Scar

#HarveyDent
Joined
Feb 11, 2007
Messages
6,066
Location
Sunnyvale, CA
We really liked the format last time so the last 30 mins to 1hr will be call-ins! Mahone (and everyone) I encourage you to do so :D
 

thespymachine

Smash Ace
Joined
May 23, 2006
Messages
830
Location
Henderson, NV
Missed most of the episode, and by the time I got Skype working and my video and audio working you guys were doing the post-show.
I'll be sure to be on time next time.
Thanks for doing this guys!

(Also, there's no direct link to the stream in the OP)
 

Metal Reeper

Smash Champion
Joined
Oct 20, 2006
Messages
2,285
Location
Abington PA
I hope I can finish the rest of the episode later. Good talking to all of you. And Scar im coming for you. Even if I don't win, it will be hype and fun as hell <3
 

KrIsP!

Smash Champion
Joined
Oct 8, 2007
Messages
2,599
Location
Toronto, Ontario
mahone is the homie. Deserves a badge and **** for that after party.

put your finga in de air if mahone da bess
 

Ether

Smash Ace
Joined
Sep 14, 2005
Messages
665
Location
Virginia Beach, VA
ya ether you would tune in bc scar whooped you at rom 5 LOOOOOOOOOOOL

sorry i refuse to sully pocky d's good name

it's scar

ROFL HAPPY NEW YEAR EVEYRONE

LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOL
oh lordy


10lordys


nb4fightnightcardgetsmade
 

dkuo

Smash Lord
Joined
Apr 21, 2010
Messages
1,464
Location
San Jose, CA
so considering the whole evo thing is suddenly revived...i thought this would be an interesting topic for the next episode.

a lot of people have been saying how donating to enter evo is counterproductive since we could just put the money into our own events and hosts. with that said...how would money usage be optimized assuming we started a fund/came into a sum of money/etc prior to an event? should separate funding exist outside of the simple venue/entrance fee at tournaments and how would they be used outside of this? if so what manners would be most effective for raising these funds? should swf take charge of funds and distribute them, or is it the to's responsibility for their own events? what ways could money be used to strengthen the community at its core vs individual events?

etc etc just some ideas ~_~ more questions down this vein are nice
i think it would be important to prepare for $ organization considering the community is apparently starting to take steps in reinforcing itself. ideas for funding can help, preparation for this would make us ready for once the time comes, etc

edit: not trying to say that $ for evo is bad or w/e, just a hypothetical 'how can we organize our own $'
 

Scar

#HarveyDent
Joined
Feb 11, 2007
Messages
6,066
Location
Sunnyvale, CA
Probably going to do a LITE version of the cast tonight - the agenda:

Melee at EVO?!? What's the deal?
Apex bracket pools, and bracket pools in general?
Call ins / chill fest / get pumped for Apex!
 

thespymachine

Smash Ace
Joined
May 23, 2006
Messages
830
Location
Henderson, NV
Scar was mentioning wanting to figure out how to get MioM on iTunes.

Someone help him. lol


Also, if you guys ever find the time, you should show a Melee match every podcast. Classic ones, new and epic ones, ones with hype new players, etc etc. Get some people's names out there and stuff.
 

Scar

#HarveyDent
Joined
Feb 11, 2007
Messages
6,066
Location
Sunnyvale, CA
OH ****

i guess i have to figure the itunes thing out tonight - people should be able to listen to it on their planes
 
Top Bottom