Setting up SG-1100 Netgate with AT&T BGW210

Recording this so I remember in the future:

I connect to the internet through an AT&T BGW210. Behind that sits an SG-1100 Netgate (pfSense). Behind that is my PC (plugged into Netgate LAN port) and my Google Wifi (plugged into Netgate OPT port). Netgate WAN plugs into BGW210.

Google Wifi is set to Bridge mode, meaning it will not assign IPs but will let Netgate do that.

With my PC connected directly to AT&T BGW210:
To set up AT&T: http://192.168.1.254

I set Wi-Fi (2.4 and 5 GHz) off, because I will be going through Google Wifi instead.

Once that is done, I plug the PC into the Netgate LAN port (and unplug Netgate WAN) and from a Command Prompt, type ipconfig/renew to get my new Netgate IP.

I set the IP to 172.16.1.1/24 (using Netgate setup wizard by first connecting to https://192.168.1.1) and then plug the WAN into AT&T.

Out of the box, Netgate LAN port is set up but the OPT port is turned off. Let’s turn it on.

To set up Netgate: https://172.16.1.1
To turn on the Netgate OPT port:

Interfaces > OPT
Enable: Checked
IPv4 Config Type: Static IPv4
IPv4 Address: 172.16.2.1/24

Services > DHCP Server > OPT
Enable: Checked
Range: 172.16.2.10 to 172.16.2.245

Firewall > Rules > OPT > Add
Action: Pass
Protocol: Any
Source: OPT net
Description: Default allow OPT to any rule

Now install ad block software:

System > Package Manger > Available Packages > pfBlockerNG
Install pfBlockerNG-devel

Firewall > pfBlockerNG
Make sure to select LAN and OPT for Outbound Firewall Interface

Firewall > pfBlockerNG > General
CRON Settings: Once a day

Firewall > pfBlockerNG > DNSBL > DNSBL Category (Optional)
Blacklist Category: Enable
Blacklists: Select Shallalist
Shallalist: Check Advertisements

Firewall > pfBlockerNG > Update > Run
It should download the new Shallalist.

Hopefully everything works. If you cannot talk to your Netgate, try directly connecting to it through USB. I used PuTTY to COM3 Speed 115200.

Addendum: I have a NAS connected to the BGW210. In order to see that from behind the Netgate, I added:

DNS Resolver > Host Override Options
Host: WDMyCloud
Domain: localdomain
IP Address: 192.168.1.65

On the BGW210 I went to Home Network > IP Allocation, and added 192.168.1.65 as a Fixed Allocation so the device would always be at that IP. Now I can use File Explorer to \\WDMyCloud.

Playing Squad as Squad Lead

I have recently been playing a lot of Squad. I really enjoy the Squad Leader role of the game. The role can really carry the map – a good SLs can lead a team to victory. I also like that Squad is very voice comms heavy. I find that I stutter a lot and forget words when trying to talk to other people in “quick” situations and the game gives me a chance to get better at speaking and making decisions. Or even having to change plans as the battlefield changes!

There are four objectives I try to reach when playing as SL (listed in order of importance):

  • Reduce Walking – only the Squad Lead can place Rally Points and HABs, so make sure you are close to the battle. Don’t get too close (so hard to gauge this!), don’t be too far away. Make it so your guys can get in there and do what they need to do. You need to enable them.
  • Give Direction – “We’re going to defend this point for a while.” “Let’s move on this flag together.” “Let’s search for their HAB over here.”
  • Be Aware of the Big Picture – I try to watch how the map overall is going and let others know. “They just blew past us, we need to fall back to the last point.” “The next point is captured and safe, so let’s leave this point and move up.” “The enemy keeps coming from this direction so let’s push out and take out their HAB or Rally.”
  • Encouragement – “Hey that was a great shot.” “Thanks for building.” “Thanks for the supplies!” Actively marking the map when teammates report enemy. “Hey you did a good job dying over there, that distraction bought us enough time to sneak around here.”

These are some things I try not to do:

  • Tell people what role to play or demand someone pick medic.
  • Tell people to do a logi run. (I hate logi runs, so why should I make you?)
  • Take another squad’s supplies or logi without asking. This includes using their supplies to build a Hesco wall/repair station.
  • Put up so many defenses around the base that people can’t get out.

Here are some recordings I made so I could re-watch and see what I was doing wrong. I’ve noticed sometimes I miss important comms or I get too hyper.

P.S. The best way to avoid being shot that I know of is to: be where the enemy doesn’t expect you to be! E.g. flank!
P.P.S. I like to place people into fireteams at the start because then I can see at the end of the map how many people stayed through the entire thing. It also means if a FTL leaves, then another person becomes FTL without me having to think about it. I like to place people who are looking out for the enemy as FTL. Usually engineers, snipers, and LAT.

About Recording

I’m using a great, free program called OBS Studio. I’ve been messing with the settings and this is what I’m using for now:

Video Bitrate: 15000 Kbps (Based on YouTube Recommended Settings)
Recording Quality: Indistinguishable Quality, Large File Size
Recording Format: mp4
Base Resolution: 1920x1080
Output Resolution: 1280x720
Downscale Filter: Lanczos (Sharpened scaling, 32 samples)
FPS: 60

Sound was really difficult to get just right.

Enable Push-to-talk (Hotkeys: V, B, G)
Desktop Audio: -8.3 dB
Mic/Aux: 12.1 dB
Squad Effects Volume: 58% Music Volume: 58%

Freeze Tag Reminisced

logo

Hopefully, when you were a kid you had a chance to play Freeze Tag on the playground. That’s where someone is “it” and when they touch or “tag” someone, that person has to stay frozen. If a friend comes up and taps them then they are unfrozen. It usually ends up with a mass of frozen people in weird poses and is a lot of fun.

Freeze Tag on the computer, on the other hand, started as a modification to the game Quake 2, which I wrote in 1997 (under the handle Doolittle). The idea was simple, take a team deathmatch game, and when you kill someone on the other side, they don’t die, they freeze in place. If you can freeze the entire enemy team then your team scores a point and everyone is unfrozen. If you run up to a frozen teammate and stand by them for three seconds then they unfreeze and can rejoin the fight. A lot of fun situations can happen with this very simple concept. You can hide out and shoot someone as they try to unfreeze someone. You can get a bunch of enemy guys to follow you, ditch them and return to your frozen teammates to save them. You could be the last one left alive, desperately trying to unfreeze a teammate.

motw

The concept of Freeze Tag for Quake 2 came about as I was playing a popular modification called Jailbreak. In this game mode, when you kill the enemy team, they would respawn back in your base’s jail. If you went to the enemy team’s base and found their jail, you could press a button to release your teammates. It was very fun, but I spent a lot of time just sitting in jail wondering what was happening. The thought occurred to me, what if when you died you just stayed in the middle of the battlefield so you could watch the others? Another factor was that Jailbreak required custom maps to work. You had to have a map with two bases and jails. I didn’t have this type of skill set. I wanted to program a modification, but I wanted it to be very minimal as far as artistic output was concerned. If I did implement the Freeze Tag idea, it would work on any map.

The cool part of the story, for me anyways, was this: it was right at a time in my life where I was picking a career. I really enjoyed computers and thought basic programming was neat, but I hadn’t done any project outside of a school homework assignment. The Quake 1 source code had been released as a programming language called QuakeC. For some reason I had skipped tinkering with this. When Quake 2 came out, and I heard the source code was written in plain ANSI C, I decided to check it out. I had done Turbo Pascal, but this was my first time seeing C. Another thing that scared me was the source was made up of more than eighty files. I had thought it would be one file!

So when the concept of Freeze Tag hit me, and I thought about making it into a mod, it was a very difficult two weeks until I had an actual prototype working. During that time I was very much tempted to give up and go tell someone else, “hey I have a cool idea, do you think you can execute it?” But I pushed through, and got something going, and I released it and people started playing it. It was really fun logging on to a game server and seeing people come on for the first time and ask in chat “what on earth is this?” I’ll never forget seeing one person say, “This is stupid. This won’t last three days!” Slowly people got into it and then they started telling their friends and I got lots of feedback. This really encouraged me to keep working on Freeze Tag. I ended up adding a lot of features because of this feedback loop.

One of the things added was a grappling hook, by Perecli Manole, which acted like real physics. Gravity would pull you down as you swung. I made it so that if you died while grappling then you might have a chance of just hanging there frozen. I didn’t tell anyone I had done this, and when I released the new version I made sure to be there when people were playing. Suddenly someone said on chat something like, “Ahhh! There’s some dude frozen here swinging back and forth from the ceiling”. I also made it so you could grapple the frozen bodies and drag them to some dark corner so people couldn’t find their teammates and release them.

Another cool thing I added was if you pressed a button while you were frozen your game character would say “helppppp meeee” or “it huuuurts” in a crackly voice. This was actually taken from the Quake 2 sounds. If you were frozen, I also gave you an option to see the view from other frozen people, but if someone shot your frozen body, your screen would zip back into your body. This gave your captors a chance to taunt you. Adding little touches like this was fun. For the Quake 3 version, I was contacted by a professional voice over guy, Jeff Wros. He said he wanted to help me record other cries for help. I was completely blown away by this.

shot1

shot2

The Quake 3 version was also fun in that the game already had bots. It took a while but I was able to figure out how to get the bots to run over and help people thaw. The bot code had a section where if the bot saw someone holding a flag in Capture the Flag, they would go stand near them and guard. I simply made the bots think frozen people had the flag, and had them stand close by when guarding. This gave the cool illusion that they were trying to rescue you.

shot3

shot4

id Software, the people I idolized and who wrote the Quake games, finally sort of acknowledged my modification when they added a game mode to QuakeLive: Freeze Tag! And soon the game Doom will be out with Freeze Tag as well.

Because of the Freeze Tag mod, I realized I loved programming and it was something I could do as a career. It gave me confidence. I really thank the Lord for this incredible turn of events: that I was able to figure out the source code, that this happened right as I was choosing a career, that people came around to support me.

Source at GitHub: getfreeze

Way back machine: Planet Quake talking about Freeze, being top 10 mod of 1998, shout out to Clan SZT and LKFF, and a Blue’s News announcement

Basic SocketAsyncEventArgs Server and Client

A while ago I tried to write a simple server and client that worked with the SocketAsyncEventArgs class. I also used BlockingCollection which was introduced in .NET 4.

Here’s the client executable:

using System;
using System.Text;
using System.Net;
using System.Threading;
using UdpLibrary;

namespace Client
{
class Client
{
static UdpSocket socket;
static void Main(string[] args)
{
socket = new UdpSocket();
socket.Bind(IPAddress.Any);

// Start a thread that prints anything sent to us
new Thread(() => printit()).Start();
string s;
while (true)
{
s = Console.ReadLine();
// Send input to server 100 times
for (int i = 0; i < 100; i++)
socket.Send(IPAddress.Loopback, 10100, Encoding.UTF8.GetBytes(s));
}
}

static void printit()
{
EndPoint ip;
byte[] buffer;
string s;
while (true)
{
socket.Receive(out ip, out buffer);
// Print out anything we receive
s = Encoding.UTF8.GetString(buffer);
Console.WriteLine(ip.ToString() + " " + s);
}
}
}
}

The server executable:

using System;
using System.Text;
using System.Net;
using UdpLibrary;

namespace Server
{
class Server
{
static void Main(string[] args)
{
UdpSocket socket = new UdpSocket();
socket.Bind(IPAddress.Loopback, 10100);

EndPoint ip;
byte[] buffer;
string s;
while (true)
{
socket.Receive(out ip, out buffer);
s = Encoding.UTF8.GetString(buffer);
// Print out what you recv then send back echo
Console.WriteLine(ip.ToString() + " " + s);
socket.Send(((IPEndPoint)ip).Address, ((IPEndPoint)ip).Port, Encoding.UTF8.GetBytes(s));
}
}
}
}

The “UdpLibrary” both executables reference:

using System;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Collections.Concurrent;

namespace UdpLibrary
{
public class UdpSocket
{
bool running;
int _transferDelay;
double _loss;
Random rnd;
Socket socket;
struct PacketStruct
{
public EndPoint ip;
public byte[] buffer;
}
BlockingCollection<PacketStruct> sendQueue;
BlockingCollection<PacketStruct> receiveQueue;

public UdpSocket()
{
running = false;
sendQueue = new BlockingCollection<PacketStruct>();
receiveQueue = new BlockingCollection<PacketStruct>();
rnd = new Random();
}

~UdpSocket()
{
running = false;
}

public bool Send(IPAddress address, int port, byte[] buffer, int timeout = -1)
{
// Don't really send, but add to the queue to be sent out
PacketStruct tmp;
tmp.ip = new IPEndPoint(address, port);
tmp.buffer = new byte[buffer.Length];
Buffer.BlockCopy(buffer, 0, tmp.buffer, 0, buffer.Length);
return sendQueue.TryAdd(tmp, timeout);
}

public bool Receive(out EndPoint ip, out byte[] buffer, int timeout = -1)
{
// See if there's anything in the queue for us to receive
PacketStruct tmp;
bool ret = receiveQueue.TryTake(out tmp, timeout);
if (ret)
{
ip = tmp.ip;
buffer = new byte[tmp.buffer.Length];
Buffer.BlockCopy(tmp.buffer, 0, buffer, 0, tmp.buffer.Length);
}
else
{
ip = null;
buffer = null;
}
return ret;
}

public void Bind(IPAddress address, int port = 0, int transferDelay = 0, double loss = 0)
{
if (running)
return;
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
try
{
socket.Bind(new IPEndPoint(address, port));
}
catch
{
return;
}
_transferDelay = transferDelay;
_loss = loss;

// Bind to port and start a thread
Thread thread = new Thread(() => ThreadProc());
thread.Start();
}

void ThreadProc()
{
running = true;

byte[] buffer = new byte[1300];
SocketAsyncEventArgs receiveEvent = new SocketAsyncEventArgs();
receiveEvent.Completed += receiveEvent_Completed;
receiveEvent.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
receiveEvent.SetBuffer(buffer, 0, buffer.Length);

if (!socket.ReceiveMessageFromAsync(receiveEvent))
throw new NotImplementedException();

PacketStruct tmp;
while (running)
{
sendQueue.TryTake(out tmp, -1);

SocketAsyncEventArgs sendEvent = new SocketAsyncEventArgs();
sendEvent.Completed += sendEvent_Completed;
sendEvent.RemoteEndPoint = tmp.ip;
sendEvent.SetBuffer(tmp.buffer, 0, tmp.buffer.Length);

if (!socket.SendToAsync(sendEvent))
throw new NotImplementedException();
}
}

void sendEvent_Completed(object sender, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success && e.LastOperation == SocketAsyncOperation.SendTo)
{
PacketStruct tmp;
if (sendQueue.TryTake(out tmp))
{
e.RemoteEndPoint = tmp.ip;
e.SetBuffer(tmp.buffer, 0, tmp.buffer.Length);

if (!((Socket)sender).SendToAsync(e))
throw new NotImplementedException();
}
else
{
e.Completed -= sendEvent_Completed;
}
return;
}
throw new NotImplementedException();
}

void receiveEvent_Completed(object sender, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.MessageSize)
{
if (!((Socket)sender).ReceiveMessageFromAsync(e))
throw new NotImplementedException();
return;
}
if (e.SocketError == SocketError.Success && e.LastOperation == SocketAsyncOperation.ReceiveMessageFrom)
{
if (_loss != 0)
{
lock (rnd)
{
if (rnd.NextDouble() < _loss)
{
if (!((Socket)sender).ReceiveMessageFromAsync(e))
throw new NotImplementedException();
return;
}
}
}

if (_transferDelay != 0)
Thread.Sleep(_transferDelay);

PacketStruct tmp;
tmp.ip = e.RemoteEndPoint;
tmp.buffer = new byte[e.BytesTransferred];
Buffer.BlockCopy(e.Buffer, 0, tmp.buffer, 0, e.BytesTransferred);
receiveQueue.TryAdd(tmp, -1);

if (!((Socket)sender).ReceiveMessageFromAsync(e))
throw new NotImplementedException();
return;
}
if (e.SocketError == SocketError.ConnectionReset)
{
}
throw new NotImplementedException();
}
}
}

Maybe this can help someone?