github.com/metaworking/channeld@v0.7.3/pkg/channeld/spatial_test.go (about)

     1  package channeld
     2  
     3  import (
     4  	"math"
     5  	"net"
     6  	"testing"
     7  
     8  	"github.com/metaworking/channeld/pkg/channeldpb"
     9  	"github.com/metaworking/channeld/pkg/common"
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  func init() {
    14  	InitLogs()
    15  }
    16  
    17  func TestUpdateSpatialInterest(t *testing.T) {
    18  
    19  }
    20  
    21  func TestConeAOI(t *testing.T) {
    22  	// 1-by-1-grid world
    23  	ctl1 := &StaticGrid2DSpatialController{
    24  		WorldOffsetX:             0,
    25  		WorldOffsetZ:             0,
    26  		GridWidth:                10,
    27  		GridHeight:               10,
    28  		GridCols:                 1,
    29  		GridRows:                 1,
    30  		ServerCols:               1,
    31  		ServerRows:               1,
    32  		ServerInterestBorderSize: 0,
    33  	}
    34  
    35  	query1 := &channeldpb.SpatialInterestQuery{
    36  		ConeAOI: &channeldpb.SpatialInterestQuery_ConeAOI{
    37  			Center: &channeldpb.SpatialInfo{
    38  				X: 5,
    39  				Z: 5,
    40  			},
    41  			Direction: &channeldpb.SpatialInfo{
    42  				X: 1,
    43  				Z: 0,
    44  			},
    45  			Radius: 1,
    46  			Angle:  math.Pi / 4,
    47  		},
    48  	}
    49  
    50  	result, err := ctl1.QueryChannelIds(query1)
    51  	assert.NoError(t, err)
    52  	assert.Contains(t, result, common.ChannelId(65536))
    53  
    54  	// 4-by-1-grid world
    55  	ctl2 := &StaticGrid2DSpatialController{
    56  		WorldOffsetX:             0,
    57  		WorldOffsetZ:             0,
    58  		GridWidth:                10,
    59  		GridHeight:               10,
    60  		GridCols:                 4,
    61  		GridRows:                 1,
    62  		ServerCols:               1,
    63  		ServerRows:               1,
    64  		ServerInterestBorderSize: 0,
    65  	}
    66  
    67  	query2 := &channeldpb.SpatialInterestQuery{
    68  		ConeAOI: &channeldpb.SpatialInterestQuery_ConeAOI{
    69  			Center: &channeldpb.SpatialInfo{
    70  				X: 0,
    71  				Z: 5,
    72  			},
    73  			Direction: &channeldpb.SpatialInfo{
    74  				X: 1,
    75  				Z: 0,
    76  			},
    77  			Radius: 1,
    78  			Angle:  math.Pi / 4,
    79  		},
    80  	}
    81  
    82  	result, err = ctl2.QueryChannelIds(query2)
    83  	assert.NoError(t, err)
    84  	assert.Contains(t, result, common.ChannelId(65536))
    85  
    86  	query2.ConeAOI.Radius = 25
    87  	result, err = ctl2.QueryChannelIds(query2)
    88  	assert.NoError(t, err)
    89  	assert.Len(t, result, 3)
    90  
    91  	query2.ConeAOI.Radius = 100
    92  	result, err = ctl2.QueryChannelIds(query2)
    93  	assert.NoError(t, err)
    94  	assert.Len(t, result, 4)
    95  
    96  	query2.ConeAOI.Direction = &channeldpb.SpatialInfo{
    97  		X: 0,
    98  		Z: 1,
    99  	}
   100  
   101  	result, err = ctl2.QueryChannelIds(query2)
   102  	assert.NoError(t, err)
   103  	assert.Len(t, result, 1)
   104  
   105  	/* 3-by-3-grid world
   106  	-------------------------
   107  	| 65542 | 65543 | 65544 |
   108  	-------------------------
   109  	| 65539 | 65540 | 65541 |
   110  	-------------------------
   111  	| 65536 | 65537 | 65538 |
   112  	-------------------------
   113  	*/
   114  	ctl3 := &StaticGrid2DSpatialController{
   115  		WorldOffsetX:             0,
   116  		WorldOffsetZ:             0,
   117  		GridWidth:                10,
   118  		GridHeight:               10,
   119  		GridCols:                 3,
   120  		GridRows:                 3,
   121  		ServerCols:               1,
   122  		ServerRows:               1,
   123  		ServerInterestBorderSize: 0,
   124  	}
   125  
   126  	query3 := &channeldpb.SpatialInterestQuery{
   127  		ConeAOI: &channeldpb.SpatialInterestQuery_ConeAOI{
   128  			Center: &channeldpb.SpatialInfo{
   129  				X: 5,
   130  				Z: 5,
   131  			},
   132  			Direction: &channeldpb.SpatialInfo{
   133  				X: 1,
   134  				Z: 0,
   135  			},
   136  			Radius: 100,
   137  			Angle:  0.1,
   138  		},
   139  	}
   140  
   141  	/*
   142  		-------------------------
   143  		|       |       |       |
   144  		-------------------------
   145  		|       |       |       |
   146  		-------------------------
   147  		| 65536 | 65537 | 65538 |
   148  		-------------------------
   149  	*/
   150  	result, err = ctl3.QueryChannelIds(query3)
   151  	assert.NoError(t, err)
   152  	assert.Len(t, result, 3)
   153  
   154  	/*
   155  		-------------------------
   156  		|       |       | 65544 |
   157  		-------------------------
   158  		|       | 65540 | 65541 |
   159  		-------------------------
   160  		| 65536 | 65537 | 65538 |
   161  		-------------------------
   162  	*/
   163  	query3.ConeAOI.Angle = math.Pi / 4
   164  	result, err = ctl3.QueryChannelIds(query3)
   165  	assert.NoError(t, err)
   166  	assert.Len(t, result, 6)
   167  
   168  	/*
   169  		-------------------------
   170  		| 65542 |       |       |
   171  		-------------------------
   172  		| 65539 | 65540 |       |
   173  		-------------------------
   174  		| 65536 |       |       |
   175  		-------------------------
   176  	*/
   177  	query3.ConeAOI.Center = &channeldpb.SpatialInfo{
   178  		X: 15,
   179  		Z: 15,
   180  	}
   181  	query3.ConeAOI.Direction = &channeldpb.SpatialInfo{
   182  		X: -1,
   183  		Z: 0,
   184  	}
   185  	result, err = ctl3.QueryChannelIds(query3)
   186  	assert.NoError(t, err)
   187  	assert.Len(t, result, 4)
   188  
   189  	/*
   190  		-------------------------
   191  		|       |       |       |
   192  		-------------------------
   193  		| 65539 |       |       |
   194  		-------------------------
   195  		| 65536 | 65537 |       |
   196  		-------------------------
   197  	*/
   198  	query3.ConeAOI.Center = &channeldpb.SpatialInfo{
   199  		X: 5,
   200  		Z: 15,
   201  	}
   202  	query3.ConeAOI.Direction = &channeldpb.SpatialInfo{
   203  		X: 0,
   204  		Z: -1,
   205  	}
   206  	result, err = ctl3.QueryChannelIds(query3)
   207  	assert.NoError(t, err)
   208  	assert.Len(t, result, 3)
   209  
   210  	// 4-by-1-grid world
   211  	ctl4 := &StaticGrid2DSpatialController{
   212  		WorldOffsetX:             -2000,
   213  		WorldOffsetZ:             -500,
   214  		GridWidth:                1000,
   215  		GridHeight:               1000,
   216  		GridCols:                 4,
   217  		GridRows:                 1,
   218  		ServerCols:               2,
   219  		ServerRows:               1,
   220  		ServerInterestBorderSize: 1,
   221  	}
   222  
   223  	query4 := &channeldpb.SpatialInterestQuery{
   224  		ConeAOI: &channeldpb.SpatialInterestQuery_ConeAOI{
   225  			Center: &channeldpb.SpatialInfo{
   226  				X: 1250,
   227  				Y: 118,
   228  			},
   229  			Direction: &channeldpb.SpatialInfo{
   230  				X: -0.087,
   231  				Z: 0.996,
   232  			},
   233  			Angle:  0.5236,
   234  			Radius: 30000,
   235  		},
   236  	}
   237  
   238  	result, err = ctl4.QueryChannelIds(query4)
   239  	assert.NoError(t, err)
   240  	assert.Len(t, result, 1)
   241  
   242  }
   243  
   244  func TestSphereAOI(t *testing.T) {
   245  	// 1-by-1-grid world
   246  	ctl1 := &StaticGrid2DSpatialController{
   247  		WorldOffsetX:             0,
   248  		WorldOffsetZ:             0,
   249  		GridWidth:                10,
   250  		GridHeight:               10,
   251  		GridCols:                 1,
   252  		GridRows:                 1,
   253  		ServerCols:               1,
   254  		ServerRows:               1,
   255  		ServerInterestBorderSize: 0,
   256  	}
   257  
   258  	query1 := &channeldpb.SpatialInterestQuery{
   259  		SphereAOI: &channeldpb.SpatialInterestQuery_SphereAOI{
   260  			Center: &channeldpb.SpatialInfo{
   261  				X: 5,
   262  				Y: 0,
   263  				Z: 5,
   264  			},
   265  			Radius: 1,
   266  		},
   267  	}
   268  
   269  	result, err := ctl1.QueryChannelIds(query1)
   270  	assert.NoError(t, err)
   271  	assert.Contains(t, result, common.ChannelId(65536))
   272  
   273  	query1.SphereAOI.Radius = 100
   274  	result, err = ctl1.QueryChannelIds(query1)
   275  	assert.NoError(t, err)
   276  	assert.Contains(t, result, common.ChannelId(65536))
   277  
   278  	// 2-by-2-grid world
   279  	ctl2 := &StaticGrid2DSpatialController{
   280  		WorldOffsetX:             -5,
   281  		WorldOffsetZ:             -5,
   282  		GridWidth:                5,
   283  		GridHeight:               5,
   284  		GridCols:                 2,
   285  		GridRows:                 2,
   286  		ServerCols:               1,
   287  		ServerRows:               1,
   288  		ServerInterestBorderSize: 0,
   289  	}
   290  
   291  	query2 := &channeldpb.SpatialInterestQuery{
   292  		SphereAOI: &channeldpb.SpatialInterestQuery_SphereAOI{
   293  			Center: &channeldpb.SpatialInfo{
   294  				X: 0,
   295  				Y: 0,
   296  				Z: 0,
   297  			},
   298  			Radius: 1,
   299  		},
   300  	}
   301  
   302  	result, err = ctl2.QueryChannelIds(query2)
   303  	assert.NoError(t, err)
   304  	assert.Len(t, result, 4)
   305  
   306  	query2.SphereAOI.Center.X = 4.9
   307  	query2.SphereAOI.Center.Z = 4.9
   308  	result, err = ctl2.QueryChannelIds(query2)
   309  	assert.NoError(t, err)
   310  	assert.Len(t, result, 1)
   311  	assert.Contains(t, result, common.ChannelId(65539))
   312  
   313  	query2.SphereAOI.Radius = 4.9
   314  	result, err = ctl2.QueryChannelIds(query2)
   315  	assert.NoError(t, err)
   316  	// Should only contain 65539
   317  	assert.Len(t, result, 1)
   318  
   319  	query2.SphereAOI.Radius = 10
   320  	result, err = ctl2.QueryChannelIds(query2)
   321  	assert.NoError(t, err)
   322  	// Should contain 65536, 65537, 65538, 65539
   323  	assert.Len(t, result, 4)
   324  
   325  	// 3-by-3-grid world
   326  	ctl3 := &StaticGrid2DSpatialController{
   327  		WorldOffsetX:             -150,
   328  		WorldOffsetZ:             -150,
   329  		GridWidth:                100,
   330  		GridHeight:               100,
   331  		GridCols:                 3,
   332  		GridRows:                 3,
   333  		ServerCols:               1,
   334  		ServerRows:               1,
   335  		ServerInterestBorderSize: 0,
   336  	}
   337  
   338  	query3 := &channeldpb.SpatialInterestQuery{
   339  		SphereAOI: &channeldpb.SpatialInterestQuery_SphereAOI{
   340  			Center: &channeldpb.SpatialInfo{
   341  				X: 0,
   342  				Y: 0,
   343  				Z: 0,
   344  			},
   345  			Radius: 150,
   346  		},
   347  	}
   348  
   349  	result, err = ctl3.QueryChannelIds(query3)
   350  	assert.NoError(t, err)
   351  	// Should contain all channels
   352  	assert.Len(t, result, 9)
   353  
   354  	// Radious = 100 would count the top-right corner channel in the result
   355  	query3.SphereAOI.Radius = 99
   356  	result, err = ctl3.QueryChannelIds(query3)
   357  	assert.NoError(t, err)
   358  	// Should not contain corner channels
   359  	assert.Len(t, result, 5)
   360  }
   361  
   362  func TestBoxAOI(t *testing.T) {
   363  	// 1-by-1-grid world
   364  	ctl1 := &StaticGrid2DSpatialController{
   365  		WorldOffsetX:             0,
   366  		WorldOffsetZ:             0,
   367  		GridWidth:                10,
   368  		GridHeight:               10,
   369  		GridCols:                 1,
   370  		GridRows:                 1,
   371  		ServerCols:               1,
   372  		ServerRows:               1,
   373  		ServerInterestBorderSize: 0,
   374  	}
   375  
   376  	query1 := &channeldpb.SpatialInterestQuery{
   377  		BoxAOI: &channeldpb.SpatialInterestQuery_BoxAOI{
   378  			Center: &channeldpb.SpatialInfo{
   379  				X: 5,
   380  				Y: 0,
   381  				Z: 5,
   382  			},
   383  			Extent: &channeldpb.SpatialInfo{
   384  				X: 1,
   385  				Y: 0,
   386  				Z: 1,
   387  			},
   388  		},
   389  	}
   390  
   391  	result, err := ctl1.QueryChannelIds(query1)
   392  	assert.NoError(t, err)
   393  	assert.Contains(t, result, common.ChannelId(65536))
   394  
   395  	query1.BoxAOI.Extent.X = 100
   396  	query1.BoxAOI.Extent.Z = 100
   397  	result, err = ctl1.QueryChannelIds(query1)
   398  	assert.NoError(t, err)
   399  	assert.Contains(t, result, common.ChannelId(65536))
   400  
   401  	// 2-by-2-grid world
   402  	ctl2 := &StaticGrid2DSpatialController{
   403  		WorldOffsetX:             -5,
   404  		WorldOffsetZ:             -5,
   405  		GridWidth:                5,
   406  		GridHeight:               5,
   407  		GridCols:                 2,
   408  		GridRows:                 2,
   409  		ServerCols:               1,
   410  		ServerRows:               1,
   411  		ServerInterestBorderSize: 0,
   412  	}
   413  
   414  	query2 := &channeldpb.SpatialInterestQuery{
   415  		BoxAOI: &channeldpb.SpatialInterestQuery_BoxAOI{
   416  			Center: &channeldpb.SpatialInfo{
   417  				X: 0,
   418  				Y: 0,
   419  				Z: 0,
   420  			},
   421  			Extent: &channeldpb.SpatialInfo{
   422  				X: 1,
   423  				Y: 0,
   424  				Z: 1,
   425  			},
   426  		},
   427  	}
   428  
   429  	result, err = ctl2.QueryChannelIds(query2)
   430  	assert.NoError(t, err)
   431  	assert.Len(t, result, 4)
   432  
   433  	query2.BoxAOI.Center.X = 4.9
   434  	query2.BoxAOI.Center.Z = 4.9
   435  	result, err = ctl2.QueryChannelIds(query2)
   436  	assert.NoError(t, err)
   437  	assert.Len(t, result, 1)
   438  	assert.Contains(t, result, common.ChannelId(65539))
   439  
   440  	query2.BoxAOI.Extent.X = 4.9
   441  	query2.BoxAOI.Extent.Z = 4.9
   442  	result, err = ctl2.QueryChannelIds(query2)
   443  	assert.NoError(t, err)
   444  	// Should only contain 65539
   445  	assert.Len(t, result, 1)
   446  
   447  	query2.BoxAOI.Extent.Z = 10
   448  	result, err = ctl2.QueryChannelIds(query2)
   449  	assert.NoError(t, err)
   450  	// Should contain 65539, 65537
   451  	assert.Len(t, result, 2)
   452  
   453  	// 3-by-3-grid world
   454  	ctl3 := &StaticGrid2DSpatialController{
   455  		WorldOffsetX:             -150,
   456  		WorldOffsetZ:             -150,
   457  		GridWidth:                100,
   458  		GridHeight:               100,
   459  		GridCols:                 3,
   460  		GridRows:                 3,
   461  		ServerCols:               1,
   462  		ServerRows:               1,
   463  		ServerInterestBorderSize: 0,
   464  	}
   465  
   466  	query3 := &channeldpb.SpatialInterestQuery{
   467  		BoxAOI: &channeldpb.SpatialInterestQuery_BoxAOI{
   468  			Center: &channeldpb.SpatialInfo{
   469  				X: 0,
   470  				Y: 0,
   471  				Z: 0,
   472  			},
   473  			Extent: &channeldpb.SpatialInfo{
   474  				X: 150,
   475  				Y: 0,
   476  				Z: 150,
   477  			}},
   478  	}
   479  
   480  	result, err = ctl3.QueryChannelIds(query3)
   481  	assert.NoError(t, err)
   482  	// Should contain all channels
   483  	assert.Len(t, result, 9)
   484  
   485  	query3.BoxAOI.Extent.X = 100
   486  	query3.BoxAOI.Extent.Z = 100
   487  	result, err = ctl3.QueryChannelIds(query3)
   488  	assert.NoError(t, err)
   489  	// Should still contain all channels
   490  	assert.Len(t, result, 9)
   491  }
   492  
   493  func TestGetAdjacentChannels(t *testing.T) {
   494  	// 1-by-1-grid world
   495  	ctl1 := &StaticGrid2DSpatialController{
   496  		WorldOffsetX:             0,
   497  		WorldOffsetZ:             0,
   498  		GridWidth:                10,
   499  		GridHeight:               10,
   500  		GridCols:                 1,
   501  		GridRows:                 1,
   502  		ServerCols:               1,
   503  		ServerRows:               1,
   504  		ServerInterestBorderSize: 1,
   505  	}
   506  	channelIds, err := ctl1.GetAdjacentChannels(GlobalSettings.SpatialChannelIdStart)
   507  	assert.NoError(t, err)
   508  	assert.Empty(t, channelIds)
   509  
   510  	// 2-by-2-grid world
   511  	ctl2 := &StaticGrid2DSpatialController{
   512  		WorldOffsetX:             -5,
   513  		WorldOffsetZ:             -5,
   514  		GridWidth:                5,
   515  		GridHeight:               5,
   516  		GridCols:                 2,
   517  		GridRows:                 2,
   518  		ServerCols:               1,
   519  		ServerRows:               1,
   520  		ServerInterestBorderSize: 0,
   521  	}
   522  	channelIds, err = ctl2.GetAdjacentChannels(GlobalSettings.SpatialChannelIdStart)
   523  	assert.NoError(t, err)
   524  	assert.Len(t, channelIds, 3)
   525  
   526  }
   527  
   528  func TestCreateSpatialChannels3(t *testing.T) {
   529  	InitChannels()
   530  
   531  	// 2-by-2-grid world, 1:1 grid:server; servers don't have border
   532  	ctl := &StaticGrid2DSpatialController{
   533  		WorldOffsetX:             0,
   534  		WorldOffsetZ:             0,
   535  		GridWidth:                33,
   536  		GridHeight:               77,
   537  		GridCols:                 2,
   538  		GridRows:                 2,
   539  		ServerCols:               2,
   540  		ServerRows:               2,
   541  		ServerInterestBorderSize: 0,
   542  	}
   543  
   544  	testConn := createTestConnection()
   545  	ctx := MessageContext{
   546  		MsgType:    channeldpb.MessageType_CREATE_CHANNEL,
   547  		Msg:        &channeldpb.CreateChannelMessage{},
   548  		Connection: testConn,
   549  	}
   550  
   551  	for {
   552  		channels, err := ctl.CreateChannels(ctx)
   553  		if err != nil {
   554  			break
   555  		} else {
   556  			assert.Len(t, channels, 1)
   557  		}
   558  	}
   559  	assert.Empty(t, testConn.subscribedChannels)
   560  
   561  	testConn.closing = true
   562  	ctl.Tick()
   563  	assert.EqualValues(t, 0, ctl.nextServerIndex())
   564  
   565  	testConn.closing = false
   566  	channels, err := ctl.CreateChannels(ctx)
   567  	assert.NoError(t, err)
   568  	assert.EqualValues(t, channels[0].id, GlobalSettings.SpatialChannelIdStart)
   569  	assert.EqualValues(t, 1, ctl.nextServerIndex())
   570  }
   571  
   572  func TestCreateSpatialChannels2(t *testing.T) {
   573  	InitChannels()
   574  
   575  	// 1-by-1-grid world consists of 1-by-1-grid server
   576  	ctl := &StaticGrid2DSpatialController{
   577  		WorldOffsetX:             0,
   578  		WorldOffsetZ:             0,
   579  		GridWidth:                10,
   580  		GridHeight:               10,
   581  		GridCols:                 1,
   582  		GridRows:                 1,
   583  		ServerCols:               1,
   584  		ServerRows:               1,
   585  		ServerInterestBorderSize: 1,
   586  	}
   587  
   588  	testConn := createTestConnection()
   589  	ctx := MessageContext{
   590  		MsgType:    channeldpb.MessageType_CREATE_CHANNEL,
   591  		Msg:        &channeldpb.CreateChannelMessage{},
   592  		Connection: testConn,
   593  	}
   594  
   595  	channels, err := ctl.CreateChannels(ctx)
   596  	assert.NoError(t, err)
   597  	assert.Len(t, channels, 1)
   598  	assert.Empty(t, testConn.subscribedChannels)
   599  
   600  	testConn.closing = true
   601  	ctl.Tick()
   602  	assert.EqualValues(t, 0, ctl.nextServerIndex())
   603  
   604  	testConn.closing = false
   605  	channels, err = ctl.CreateChannels(ctx)
   606  	assert.NoError(t, err)
   607  	assert.EqualValues(t, channels[0].id, GlobalSettings.SpatialChannelIdStart)
   608  	assert.EqualValues(t, 1, ctl.nextServerIndex())
   609  	_, err = ctl.CreateChannels(ctx)
   610  	assert.Error(t, err)
   611  }
   612  
   613  func TestCreateSpatialChannels1(t *testing.T) {
   614  	InitChannels()
   615  
   616  	// 4-by-3-grid world consists of 2-by-1-grid servers - there are 2x3=6 servers.
   617  	ctl := &StaticGrid2DSpatialController{
   618  		WorldOffsetX:             -40,
   619  		WorldOffsetZ:             -60,
   620  		GridWidth:                20,
   621  		GridHeight:               40,
   622  		GridCols:                 4,
   623  		GridRows:                 3,
   624  		ServerCols:               2,
   625  		ServerRows:               3,
   626  		ServerInterestBorderSize: 1,
   627  	}
   628  
   629  	conns := make([]*testConnection, 6)
   630  	for i := range conns {
   631  		conns[i] = createTestConnection()
   632  	}
   633  
   634  	ctx := MessageContext{
   635  		MsgType: channeldpb.MessageType_CREATE_CHANNEL,
   636  		Msg:     &channeldpb.CreateChannelMessage{},
   637  	}
   638  
   639  	ctx.Connection = conns[0]
   640  	server0Channels, _ := ctl.CreateChannels(ctx)
   641  	assert.Len(t, server0Channels, 2)
   642  	assert.Equal(t, GlobalSettings.SpatialChannelIdStart+0, server0Channels[0].id)
   643  	assert.Equal(t, GlobalSettings.SpatialChannelIdStart+1, server0Channels[1].id)
   644  
   645  	for i := 1; i < 6; i++ {
   646  		ctx.Connection = conns[i]
   647  		channels, err := ctl.CreateChannels(ctx)
   648  		assert.NoError(t, err)
   649  		assert.Len(t, channels, 2)
   650  	}
   651  	assert.EqualValues(t, 6, ctl.nextServerIndex())
   652  
   653  	/* Grids and Servers:
   654  	3  2  |  1  0
   655  	-------------
   656  	7  6  |  5  4
   657  	-------------
   658  	11 10 |  9  8
   659  	*/
   660  	assert.Contains(t, conns[0].subscribedChannels, GlobalSettings.SpatialChannelIdStart+2)
   661  	assert.Contains(t, conns[0].subscribedChannels, GlobalSettings.SpatialChannelIdStart+4)
   662  	assert.Contains(t, conns[0].subscribedChannels, GlobalSettings.SpatialChannelIdStart+5)
   663  
   664  	assert.Contains(t, conns[1].subscribedChannels, GlobalSettings.SpatialChannelIdStart+1)
   665  	assert.Contains(t, conns[1].subscribedChannels, GlobalSettings.SpatialChannelIdStart+6)
   666  	assert.Contains(t, conns[1].subscribedChannels, GlobalSettings.SpatialChannelIdStart+7)
   667  
   668  	assert.Contains(t, conns[2].subscribedChannels, GlobalSettings.SpatialChannelIdStart+0)
   669  	assert.Contains(t, conns[2].subscribedChannels, GlobalSettings.SpatialChannelIdStart+1)
   670  	assert.Contains(t, conns[2].subscribedChannels, GlobalSettings.SpatialChannelIdStart+6)
   671  	assert.Contains(t, conns[2].subscribedChannels, GlobalSettings.SpatialChannelIdStart+8)
   672  	assert.Contains(t, conns[2].subscribedChannels, GlobalSettings.SpatialChannelIdStart+9)
   673  
   674  	assert.Contains(t, conns[3].subscribedChannels, GlobalSettings.SpatialChannelIdStart+2)
   675  	assert.Contains(t, conns[3].subscribedChannels, GlobalSettings.SpatialChannelIdStart+3)
   676  	assert.Contains(t, conns[3].subscribedChannels, GlobalSettings.SpatialChannelIdStart+5)
   677  	assert.Contains(t, conns[3].subscribedChannels, GlobalSettings.SpatialChannelIdStart+10)
   678  	assert.Contains(t, conns[3].subscribedChannels, GlobalSettings.SpatialChannelIdStart+11)
   679  
   680  	assert.Contains(t, conns[5].subscribedChannels, GlobalSettings.SpatialChannelIdStart+6)
   681  	assert.Contains(t, conns[5].subscribedChannels, GlobalSettings.SpatialChannelIdStart+7)
   682  	assert.Contains(t, conns[5].subscribedChannels, GlobalSettings.SpatialChannelIdStart+9)
   683  }
   684  
   685  type testConnection struct {
   686  	sentMsgs           []MessageContext
   687  	subscribedChannels map[common.ChannelId]*Channel
   688  	closing            bool
   689  }
   690  
   691  func createTestConnection() *testConnection {
   692  	return &testConnection{
   693  		sentMsgs:           make([]MessageContext, 0),
   694  		subscribedChannels: make(map[common.ChannelId]*Channel),
   695  	}
   696  }
   697  
   698  func (c *testConnection) Id() ConnectionId {
   699  	return 0
   700  }
   701  
   702  func (c *testConnection) GetConnectionType() channeldpb.ConnectionType {
   703  	return channeldpb.ConnectionType_NO_CONNECTION
   704  }
   705  
   706  func (c *testConnection) OnAuthenticated(pit string) {
   707  
   708  }
   709  
   710  func (c *testConnection) HasAuthorityOver(ch *Channel) bool {
   711  	return false
   712  }
   713  
   714  func (c *testConnection) Close() {
   715  	c.closing = true
   716  }
   717  
   718  func (c *testConnection) IsClosing() bool {
   719  	return c.closing
   720  }
   721  
   722  func (c *testConnection) Send(ctx MessageContext) {
   723  
   724  }
   725  
   726  func (c *testConnection) SubscribeToChannel(ch *Channel, options *channeldpb.ChannelSubscriptionOptions) (*ChannelSubscription, bool) {
   727  	c.subscribedChannels[ch.id] = ch
   728  	return &ChannelSubscription{
   729  		options: *defaultSubOptions(ch.channelType),
   730  	}, false
   731  }
   732  
   733  func (c *testConnection) UnsubscribeFromChannel(ch *Channel) (*channeldpb.ChannelSubscriptionOptions, error) {
   734  	delete(c.subscribedChannels, ch.id)
   735  	return nil, nil
   736  }
   737  
   738  func (c *testConnection) sendSubscribed(ctx MessageContext, ch *Channel, connToSub ConnectionInChannel, stubId uint32, subOptions *channeldpb.ChannelSubscriptionOptions) {
   739  
   740  }
   741  
   742  func (c *testConnection) sendUnsubscribed(ctx MessageContext, ch *Channel, connToUnsub *Connection, stubId uint32) {
   743  
   744  }
   745  
   746  func (c *testConnection) HasInterestIn(spatialChId common.ChannelId) bool {
   747  	return false
   748  }
   749  
   750  func (c *testConnection) Logger() *Logger {
   751  	return rootLogger
   752  }
   753  
   754  func (c *testConnection) RemoteAddr() net.Addr {
   755  	return nil
   756  }
   757  
   758  func TestGetChannelId2(t *testing.T) {
   759  	// 9-by-8-grid world consists of 3-by-2-grid servers - there are 3x4=12 servers.
   760  	ctl := &StaticGrid2DSpatialController{
   761  		WorldOffsetX:             0,
   762  		WorldOffsetZ:             0,
   763  		GridWidth:                100,
   764  		GridHeight:               50,
   765  		GridCols:                 9,
   766  		GridRows:                 8,
   767  		ServerCols:               3,
   768  		ServerRows:               4,
   769  		ServerInterestBorderSize: 2,
   770  	}
   771  
   772  	var channelId common.ChannelId
   773  	var err error
   774  	channelId, _ = ctl.GetChannelId(common.SpatialInfo{X: 0, Z: 0})
   775  	assert.Equal(t, GlobalSettings.SpatialChannelIdStart+0, channelId)
   776  
   777  	channelId, _ = ctl.GetChannelId(common.SpatialInfo{X: 100, Z: 0})
   778  	assert.Equal(t, GlobalSettings.SpatialChannelIdStart+1, channelId)
   779  
   780  	channelId, _ = ctl.GetChannelId(common.SpatialInfo{X: 0, Z: 50})
   781  	assert.Equal(t, GlobalSettings.SpatialChannelIdStart+common.ChannelId(ctl.GridCols), channelId)
   782  
   783  	channelId, _ = ctl.GetChannelId(common.SpatialInfo{X: 899.99, Z: 399.99})
   784  	assert.Equal(t, GlobalSettings.SpatialChannelIdStart+9*8-1, channelId)
   785  
   786  	_, err = ctl.GetChannelId(common.SpatialInfo{X: -1, Z: 0})
   787  	assert.Error(t, err)
   788  
   789  	_, err = ctl.GetChannelId(common.SpatialInfo{X: math.MaxFloat64, Z: 0})
   790  	assert.Error(t, err)
   791  
   792  	_, err = ctl.GetChannelId(common.SpatialInfo{X: 0, Z: -1})
   793  	assert.Error(t, err)
   794  
   795  	_, err = ctl.GetChannelId(common.SpatialInfo{X: 900, Z: 400})
   796  	assert.Error(t, err)
   797  }
   798  
   799  func TestGetChannelId1(t *testing.T) {
   800  	// 9-by-8-grid world consists of 3-by-2-grid servers - there are 3x4=12 servers.
   801  	ctl := &StaticGrid2DSpatialController{
   802  		WorldOffsetX:             -450,
   803  		WorldOffsetZ:             -200,
   804  		GridWidth:                100,
   805  		GridHeight:               50,
   806  		GridCols:                 9,
   807  		GridRows:                 8,
   808  		ServerCols:               3,
   809  		ServerRows:               4,
   810  		ServerInterestBorderSize: 2,
   811  	}
   812  
   813  	var channelId common.ChannelId
   814  	var err error
   815  	channelId, _ = ctl.GetChannelId(common.SpatialInfo{X: -450, Z: -200})
   816  	assert.Equal(t, GlobalSettings.SpatialChannelIdStart+0, channelId)
   817  
   818  	channelId, _ = ctl.GetChannelId(common.SpatialInfo{X: -350, Z: -200})
   819  	assert.Equal(t, GlobalSettings.SpatialChannelIdStart+1, channelId)
   820  
   821  	channelId, _ = ctl.GetChannelId(common.SpatialInfo{X: -450, Z: -150})
   822  	assert.Equal(t, GlobalSettings.SpatialChannelIdStart+common.ChannelId(ctl.GridCols), channelId)
   823  
   824  	channelId, _ = ctl.GetChannelId(common.SpatialInfo{X: 0, Z: 0})
   825  	assert.Equal(t, GlobalSettings.SpatialChannelIdStart+9*4+4, channelId)
   826  
   827  	channelId, _ = ctl.GetChannelId(common.SpatialInfo{X: 449.99, Z: 199.99})
   828  	assert.Equal(t, GlobalSettings.SpatialChannelIdStart+9*8-1, channelId)
   829  
   830  	_, err = ctl.GetChannelId(common.SpatialInfo{X: -500, Z: 0})
   831  	assert.Error(t, err)
   832  
   833  	_, err = ctl.GetChannelId(common.SpatialInfo{X: 500, Z: 0})
   834  	assert.Error(t, err)
   835  
   836  	_, err = ctl.GetChannelId(common.SpatialInfo{X: 0, Z: -300})
   837  	assert.Error(t, err)
   838  
   839  	_, err = ctl.GetChannelId(common.SpatialInfo{X: 0, Z: 300})
   840  	assert.Error(t, err)
   841  
   842  	_, err = ctl.GetChannelId(common.SpatialInfo{X: 450, Z: 200})
   843  	assert.Error(t, err)
   844  }